5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Elm 0.18で作るTodoアプリ(1)

Last updated at Posted at 2017-10-04

はじめに

Webアプリのフレームワークを調査対象としてelmを選択しました。

特徴を把握するために、他のフレームワークでよく作られている、TodoアプリをWebで探したのですが、初心者に適切なサンプルが見つかりませんでした。

難易度が高かったり、elmのバージョンが古くて0.18では動かなかったりしたので、0.18の環境で自分で作ることにしました。

初めてelmを学ぶ方の参考になれば幸いです。

私自身、初めてのelmでいろいろと参考にしながら作成しているため、本筋で関係ない(使われない)ゴミデータが含まれていることもありますがご了承ください。
最終的にはゴミデータのない実装を目指し、少しずつ拡張していく予定です。

実行環境

  • OS:CentOS 7.3
  • Node:v6.11.3
  • npm: v3.10.10
  • nodebrew: v0.9.7
  • elm: v0.18

elmの導入時にnpmでつまずいたので、その時の記事は下記を参照ください。
npmのプロキシ設定の優先順位

全体設計

言語は違いますがReact.jsの下記の記事を参考にしました。
ステップバイステップReact.jsで作るTodoアプリ

TodoCreatorに関しては今回は扱わず、次回以降に扱うことになると思います。

今回のテーマ

固定値のTodoをTodoリストへ追加できるようにする

ファイル構成

  • Main.elm:大元のプログラム。基本的には配下のモジュールへ委譲するのみ。
  • TodoList.elm:Todoのリスト管理を行う

実装

Todolist.elmの作成

  • moduleの宣言とimport関連

module TodoList exposing (..)

import Html exposing (..)
import Html.Attributes exposing (class)
import Html.Events exposing (onClick)
  • モデルの定義

ここでは、ToDo型を定義し、そのListを保持するものをModelとします。
ToDoを追加するのでAddNewというMsgを定義します。

-- model
type alias ToDo = 
    { count : Int
    , item : String
    }

type alias Model = 
    { todoList : List ToDo
    }

initialModel : Model
initialModel = 
    { todoList = 
        [ ToDo 1 "item1" 
        , ToDo 2 "item2"
        ]
    }

type Msg
    = NoOp
    | AddNew ToDo
  • updateの定義

ここでは、AddNewの引数でtodoをもらい、それをtodoListへ追加することにしました。


-- update
update : Msg -> ToDo -> Model -> ( Model, Cmd Msg )
update message todo model =
    case message of
        NoOp ->
            model ! []

        AddNew todo -> 
            ( { model | todoList = model.todoList ++ [todo] }, Cmd.none )
  • viewの定義

updateButtonの定義でonClickが来たら(ToDo 4 "item4")という固定値をリストに追加します。
これで、リストに追加できることが確認できると思います。


-- view
view : Model -> Html Msg
view model = 
    div []
        [ viewList model.todoList
        ]

viewList : List ToDo -> Html Msg
viewList models = 
    div [ class "p2" ]
    [ viewItems models
    , updateButton models
    ]

viewItems : List ToDo -> Html Msg
viewItems models = 
    ul [] (List.map viewItem models)

viewItem : ToDo -> Html Msg
viewItem model = 
    li [] [
        text model.item
    ]

updateButton : List ToDo -> Html Msg
updateButton models = 
    div [] 
        [ button [ onClick (AddNew (ToDo 4 "item4")) ] [ text "Click" ] ]

Main.elmの作成

Mainは配下のモジュールに委譲するところがポイントになると思います。
親子関係のやりとりなどは下記のサイトが参考になりました。
Elmチュートリアル 合成

今回の例ではupdateやviewで処理を配下のTodoListへ委譲しています。
また、TodolistのupdateでAddNewが引数を必要としているため、Mainから委譲する時にTodoList.ToDoを渡していますが、ダミーデータです。実際はTodolist.elmにあるupdateButtonのAddNewの引数が使われます。

子の属性を親が使っていて気持ち悪いのですが、次回以降に直します。


module Main exposing (..)

import Html exposing (Html, program)
import TodoList

main : Program Never AppModel Msg
main =
    program
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

-- model
type alias AppModel =
    { todoListModel : TodoList.Model
    }

initialModel : AppModel
initialModel = 
    { todoListModel = TodoList.initialModel
    }

init : ( AppModel, Cmd Msg)
init = 
    ( initialModel, Cmd.none)

type Msg
    = TodoListMsg TodoList.Msg

-- update
update : Msg -> AppModel -> ( AppModel, Cmd Msg )
update message model = 
    case message of
        TodoListMsg subMsg ->
            let
                ( updatedTodoListModel, todoListCmd ) =
                    TodoList.update subMsg (TodoList.ToDo 0 "dummy") model.todoListModel
            in
                ( { model | todoListModel = updatedTodoListModel }, Cmd.map TodoListMsg todoListCmd )

-- subscription
subscriptions : AppModel -> Sub Msg
subscriptions model =
    Sub.none

-- view
view : AppModel -> Html Msg
view model =
    Html.div []
        [ Html.map TodoListMsg (TodoList.view model.todoListModel) 
        ]

make

オプション(--debug)を付けると状態変化が見られて便利です。

$ elm-make Main.elm --output index.html --debug

実行結果

作成したindex.htmlをブラウザで見ます。
clickボタンを押下するごとにitem4のタスクが増えていくことが分かると思います。
FF_elm_study1.png

おわりに

今回はTodoの固定値をリストへ追加するサンプルを作成しました。
次回はテキストボックスで入力した値をリストへ追加するように拡張しようと思います。
次回:Elm 0.18で作るTodoアプリ(2)

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?