17

我正在尝试从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 )

所以我的 Msg 需要输入 Cmd Msg。我怎样才能把“我的消息”变成一个 Cmd 消息?

注意:我知道有一种更简单的方法可以进行这种更改,但我试图从根本上理解 Elm

4

2 回答 2

38

真的没必要Msg变身Cmd Msg。请记住,这update只是一个函数,因此您可以递归调用它。

您的NewTopic案例处理程序可以简化为:

NewTopic newTopic ->
    update MorePlease { model | topic = newTopic}

如果您真的希望 Elm 架构为这种情况触发 Cmd,您可以按照您的要求做一个简单map的:Cmd.noneMsg

NewTopic newTopic ->
    ({ model | topic = newTopic}, Cmd.map (always MorePlease) Cmd.none)

(实际上不推荐)

于 2017-03-09T19:09:41.903 回答
12

添加以下功能:

run : msg -> Cmd msg
run m =
    Task.perform (always m) (Task.succeed ())

然后您的代码将变成:

NewTopic newTopic ->
      ({ model | topic = newTopic}, run MorePlease)
于 2018-05-30T15:11:26.793 回答