Elm-langチュートリアル から単純なアプリを変更して、最初にモデルを更新してから、別の更新をトリガーしようとしています。
update msg model =
case msg of
MorePlease ->
(model, getRandomGif model.topic)
NewGif (Ok newUrl) ->
( { model | gifUrl = newUrl }, Cmd.none)
NewGif (Err _) ->
(model, Cmd.none)
-- my addition
NewTopic newTopic ->
({ model | topic = newTopic}, MorePlease)
NewTopicブランチが原因で、これはコンパイラで失敗します。
The 3rd branch has this type:
( { gifUrl : String, topic : String }, Cmd Msg )
But the 4th is:
( { gifUrl : String, topic : String }, Msg )
したがって、私のメッセージはCmdMsgと入力する必要があります。メッセージをCmdメッセージに変換するにはどうすればよいですか?
注:この変更を行うためのより簡単な方法があることは認識していますが、私はElmをより根本的に理解しようとしています
Msg
をCmd Msg
に変える必要は本当にありません。 update
は単なる関数であるため、再帰的に呼び出すことができます。
NewTopic
ケースハンドラーは次のように簡略化できます。
NewTopic newTopic ->
update MorePlease { model | topic = newTopic}
このシナリオでElmアーキテクチャがCmdを起動することを本当に望んでいる場合は、Cmd.none
の単純なmap
を目的のMsg
に対して実行できます。
NewTopic newTopic ->
({ model | topic = newTopic}, Cmd.map (always MorePlease) Cmd.none)
(実際には推奨されません)
次の関数を追加します。
run : msg -> Cmd msg
run m =
Task.perform (always m) (Task.succeed ())
コードは次のようになります。
NewTopic newTopic ->
({ model | topic = newTopic}, run MorePlease)