引き続き、ElmでTodoListをつくっていきます。
ここで、ちょっと修正を行います。
Elmのプロの方からブログにコメントをいただけたので、そのフィードバックを反映します(嬉しい!)
型のimport
TodoListを作り始めた頃、親子コンポーネントでの型の扱いに戸惑っていました。
親で定義した型を、子でも使えずにどうしたものかと。まあ、冷静に考えればそりゃあそうなんですが。
以下、いただいたコメント。
> IDなんて型はない。とのこと。
Todo.elmで定義したIDをTodoList.elmから使うのが良いと思います。`type alias ID = Todo.ID`あるいは`import Todo exposing(ID)`。理想的には使う側はIntだと知らずに使いたいので。あと、関数型言語でリストは通常LinkedListなので新しい要素は先頭に追加することが多いです。`newTodos = newTodo :: model.todos`まぁパフォーマンスは気にするほど変わらないですが。
後半はリストに関するものですが、勉強になったのでフル引用しました。
なるほど!子コンポーネントで定義して、それを親へとimortしてくればいいんですね。
修正します。これがTodoListの現在のコードです。(modelと型定義のみ抜粋)
gista25883367d330be6ca376b8864de7691
これを以下のように変更。
gist39c365a2f1f4f7f75d3f5a1b927b1ccb
TodoListにおけるID型は、子コンポーネントであるTodoのID型ですよーと明言しました。
なので、Todo側でID型をオープンにしてあげます。
こちらがもともとのTodoです。(module文とmodelの型宣言のみ抜粋)
gist2e8886a515fedacfd8406150fc0e88eb
これを以下のように直します。
gist94d48cf1495d42e69012b548eda71e7f
module文の中にIDを追加しました。(記述位置はmodelとinitの間でいいのかな)
Addボタンのdisable
テキストエリアに文字列が入力されていない時、Todoの追加はできませんよ〜というやつ。
詳しい実装は前回の記事をご覧ください。
ここでは、僕はviewで対処を行いました。
レンダリングの際に、addText(テキストエリアに入力された値)が空ならば、AddアクションのついていないAddボタンをレンダリングしていました。
そうじゃなくて、update側で対処するんですね。
書いたコードがこちら。letの3文目が新規追加文です。
gistbaa142124526f27bb02c320a116cbf5f
なるほど〜。既存のmodelを返せば、レンダリング結果も変わりませんよね。
ボタン属性の修正
さて。updateで対処したのでview側を修正します。
これが前回書いた関数です。
gist04ab252188a36f24e9aaddbb486d2ae0
どちらの仮想DOMを返すか分岐させています。
addTextが空の場合、ボタンを押してもTodoは追加されなくなったので、この関数は消します。
代わりに、ボタンのAttributeを返す関数を書きました。
gist14adf5e9209c0bb8a9065c56e9005853
ここでは、disabledという属性を使っています。
http://package.elm-lang.org/packages/evancz/elm-html/2.0.0/Html-Attributes#disabled
disabledはBoolを渡すと、Attributeを返してくれます。要は、Trueを渡すと”無効化”を、Falseを渡すと”有効化”を返してくれます。(あくまで例えです)
以下の要素に適用可能みたいです。
さらに、viewのlet内でこの関数を使うように変更します。
gistd01e65d086aa8e2ecaf1c808c61122c5
まとめ
TodoList全体のコードを改めて。
gist6592b1eecd614b8beb8bc65575436253
フィードバックのおかげで、コードが改良されました!
disabledは便利ですね。積極的に使っていきたいです。
button
,fieldset
,input
,keygen
,optgroup
,option
,select
ortextarea
.