読者です 読者をやめる 読者になる 読者になる

コンパイラかく語りき

文系新卒プログラマーのメモ

ElmでつくるTodoList(3)

Elm

ひきつづき、ElmでTodoListをつくっていきます。

 

 前回は、Todoに任意の文字列を入力できるようにしました。

chuckwebtips.hatenablog.com

今回は、それぞれのTodoに終了機能をつけていきます。

 

終了機能の実装

チェックマーク

まず、見た目から追加します。

Todoの横あたりに✓マークを付けます。

 

コードがこちら。

gista195bf9b3b13c74ab119ff73b0bae525

新しくspanとそのスタイルを作成しました。

 

見た目はこんな感じ。

f:id:chuck0523:20160416172908p:plain

 

終了イベント

次にクリックイベントを追加します。

✓をクリックしたら、「終了状態」になるようにします。

 

TodoのModel修正

まずは、TodoのModelを変更します。

現在、TodoはModelとして、textのみを持ちます。ここに、「終了済みかどうか」というBool型のデータを追加します。

ついでなので、ID型のIDも追加します。

 

現在はこんな感じ。

gist051c842499064cc110592bc690222fa7

 

じゃん。

gistce49fef727b488329fd6b63850b17c10

Modelが増えました。

 

ついでに、init関数も作成します。

gist0cbbbbfc21a5e189072104ee599796b7

initは親コンポーネントからID型のidと、String型のtextを受け取ります。それらをinit内で、Todoのmodelとしてセットします。

 

コンパイラに怒られました。

f:id:chuck0523:20160416180411p:plain

IDなんて型はない。とのこと。

あれ、親コンポーネントで定義してるんだけどな。子コンポーネントでも定義が必要なんですかね。

 

一応、type aliasを追加しました。

gist06fd3797eb9036039d8c382b8aeb3729

 

Todoのview修正

さて、view側でエラーが出ました。

f:id:chuck0523:20160416180636p:plain

Modelは{Bool, ID, String }を期待しているのに、Stringしか指定されていないとのこと。

そりゃあそうですね。Modelを修正してしまったのだから。

 

というわけで、viewの型を変更します。

これが怒られているview。

gista8f2e3c5feb1cd2ddc8ff0de71e1fb99

 

この修正には、ちょっと時間がかかりました。

修正後のviewがこちら。

gistb020b2c31d8013d0d1ea1fb53f60b8ed

違いは、text model を text model.todoTextとしました。

前者では、modelがtextの引数となり、String扱いされてしまっていたのかもしれません。

 

TodoListの修正

さて、Todoの修正は済みましたが、TodoListとの整合性が取れなくなりました。

エラーの嵐です。

f:id:chuck0523:20160416183011p:plain

TodoList側の型指定を変更していきます。

 

Actionの修正

こちらが怒られるTodoListのActionです。

gistab574b068fb74dc59ce89c3ab9f900c9

Add関数の中に誤りがありますね。

let文の中で、Todo.initを呼んでいます。子コンポーネントであるTodoのinitですね。

ここでは、String型のmodel.addTextを渡しています。しかし、todoのmodelはいまや3つのデータ型を持ち、initも2つのデータ型を要求します。

なので、もう1つ引数を追加して、整合性を図ります。

gist2718e608ab4215053b9650f5ac12a757

 

Viewの修正

さて、Actionを修正したので、エラーが1つに減りました。

f:id:chuck0523:20160416183650p:plain

どうやら、viewの中のviewTodosという関数でエラーが発生しています。

こちらが怒られるviewTodos関数。

gist4c99f2d62cf681f58c89286461ff2b19

これも先ほどと同様に、型が間違っていますね。

Todoのview関数の型を変えてしまったので、整合性を図ります。

 

すみません、色々と修正してしまいました。

gistf6d9089df9ddd11e9e17de631f1b10e8

addressは不要だったので消しました。これにてエラーは解消。

 

f:id:chuck0523:20160416190040p:plain

ようやく終了処理の記述に入れます。

 

終了関数

Todoに戻ります。

Todoの現在のupdateは空っぽです。つまり、Todo単体でのアクションはありません。ここに、1つ関数を追加します。

 

updateの追加

DoneTodoという関数は、TodoのdoneデータをFalseからTrueにします。

gist1b8840490b9250b9f2e897814a2d0b1c

 

viewの変更

次に、viewの中にDoneTodo関数を仕込みます。

最初に作成したチェックマークにクリック関数として追加しましょう。

gist546a6b2737883f49ca9b94a52134dcd6

関数を組み込んだついでに、現在のdone状態を表示するようにしました。

model.doneをtext関数の引数に追加しました。

 

TodoListの修正

さて、Todoを修正したので、またTodoListとの整合がとれなくなってしまいました。

TodoListを修正します。

 

ちなみに、ここでもかなり時間がかかったしまったのですが、TodoList側にもActionを1つ追加しました。

Elm−Architectureでも学んだModify関数を追加しました。

たぶんなのですが、子コンポーネントのupdate関数を、親コンポーネント側でラップしているっぽいんですよね。

gista300a979e316076a2acd83f858a3e15f

 

Modify関数を渡した新たなviewTodos関数がこちら。

gistcbac044ca1ce976a552696fb7576a688

これで、Todoのview関数と整合性がとれて、コンパイルが通りました。

 

ブラウザで確認

さて、ここまでの完成品をブラウザで確認します。

まず、いくつかのTodoを追加します。

f:id:chuck0523:20160416194419p:plain

doneデータの初期状態はFalseなので、最初はみんなFalseになっています。

Elmの勉強をしたので、ElmのTodoのチェックをクリックしてみます。

 

すると、ElmのTodoのdoneデータが反転して、Trueになりました。

f:id:chuck0523:20160416194526p:plain

 

あとは、doneの値をもとに何か処理を追加すれば、終了処理の完成ですね。

 

終了スタイルの追加

おまけ的ではありますが、スタイルを追加します。

doneがTrueの時は打ち消し線を引きます。

gist42ab3d3b03018387f9978244811ff26a

 

結果はこちら。

f:id:chuck0523:20160416195452p:plain

終了したTodoには打ち消し線が引かれました!

 

 

というわけで、今回は終了処理を追加しました。

次回は、また1つ何か機能を付け加えてみます。