ひきつづき、ElmでTodoListをつくっていきます。
前回は、Todoに任意の文字列を入力できるようにしました。
今回は、それぞれのTodoに終了機能をつけていきます。
終了機能の実装
チェックマーク
まず、見た目から追加します。
Todoの横あたりに✓マークを付けます。
コードがこちら。
gista195bf9b3b13c74ab119ff73b0bae525
新しくspanとそのスタイルを作成しました。
見た目はこんな感じ。
終了イベント
次にクリックイベントを追加します。
✓をクリックしたら、「終了状態」になるようにします。
TodoのModel修正
まずは、TodoのModelを変更します。
現在、TodoはModelとして、textのみを持ちます。ここに、「終了済みかどうか」というBool型のデータを追加します。
ついでなので、ID型のIDも追加します。
現在はこんな感じ。
gist051c842499064cc110592bc690222fa7
じゃん。
gistce49fef727b488329fd6b63850b17c10
Modelが増えました。
ついでに、init関数も作成します。
gist0cbbbbfc21a5e189072104ee599796b7
initは親コンポーネントからID型のidと、String型のtextを受け取ります。それらをinit内で、Todoのmodelとしてセットします。
コンパイラに怒られました。
IDなんて型はない。とのこと。
あれ、親コンポーネントで定義してるんだけどな。子コンポーネントでも定義が必要なんですかね。
一応、type aliasを追加しました。
gist06fd3797eb9036039d8c382b8aeb3729
Todoのview修正
さて、view側でエラーが出ました。
Modelは{Bool, ID, String }を期待しているのに、Stringしか指定されていないとのこと。
そりゃあそうですね。Modelを修正してしまったのだから。
というわけで、viewの型を変更します。
これが怒られているview。
gista8f2e3c5feb1cd2ddc8ff0de71e1fb99
この修正には、ちょっと時間がかかりました。
修正後のviewがこちら。
gistb020b2c31d8013d0d1ea1fb53f60b8ed
違いは、text model を text model.todoTextとしました。
前者では、modelがtextの引数となり、String扱いされてしまっていたのかもしれません。
TodoListの修正
さて、Todoの修正は済みましたが、TodoListとの整合性が取れなくなりました。
エラーの嵐です。
TodoList側の型指定を変更していきます。
Actionの修正
こちらが怒られるTodoListのActionです。
gistab574b068fb74dc59ce89c3ab9f900c9
Add関数の中に誤りがありますね。
let文の中で、Todo.initを呼んでいます。子コンポーネントであるTodoのinitですね。
ここでは、String型のmodel.addTextを渡しています。しかし、todoのmodelはいまや3つのデータ型を持ち、initも2つのデータ型を要求します。
なので、もう1つ引数を追加して、整合性を図ります。
gist2718e608ab4215053b9650f5ac12a757
Viewの修正
さて、Actionを修正したので、エラーが1つに減りました。
どうやら、viewの中のviewTodosという関数でエラーが発生しています。
こちらが怒られるviewTodos関数。
gist4c99f2d62cf681f58c89286461ff2b19
これも先ほどと同様に、型が間違っていますね。
Todoのview関数の型を変えてしまったので、整合性を図ります。
すみません、色々と修正してしまいました。
gistf6d9089df9ddd11e9e17de631f1b10e8
addressは不要だったので消しました。これにてエラーは解消。
ようやく終了処理の記述に入れます。
終了関数
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を追加します。
doneデータの初期状態はFalseなので、最初はみんなFalseになっています。
Elmの勉強をしたので、ElmのTodoのチェックをクリックしてみます。
すると、ElmのTodoのdoneデータが反転して、Trueになりました。
あとは、doneの値をもとに何か処理を追加すれば、終了処理の完成ですね。
終了スタイルの追加
おまけ的ではありますが、スタイルを追加します。
doneがTrueの時は打ち消し線を引きます。
gist42ab3d3b03018387f9978244811ff26a
結果はこちら。
終了したTodoには打ち消し線が引かれました!
というわけで、今回は終了処理を追加しました。
次回は、また1つ何か機能を付け加えてみます。