【问题标题】:Elm - Turn Msg into Cmd MsgElm - 把 Msg 变成 Cmd Msg
【发布时间】:2017-07-30 21:51:18
【问题描述】:

我正在尝试从elm-lang tutorial 修改一个简单的应用程序,以首先更新模型,然后触发另一个更新。

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。我怎样才能把我的 Msg 变成一个 Cmd Msg?

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

【问题讨论】:

    标签: elm elm-architecture


    【解决方案1】:

    添加如下函数:

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

    你的代码会变成:

    NewTopic newTopic ->
          ({ model | topic = newTopic}, run MorePlease)
    

    【讨论】:

    • 为你的答案提供解释。
    • 我的消息有一个参数,所以语法不同,但是当接受的答案中显示的Cmd.map 无效时,使用Task.perform 对我有用。
    【解决方案2】:

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

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

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

    如果您真的希望 Elm 架构在这种情况下触发 Cmd,您可以对所需的 Msg 执行简单的 mapCmd.none

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

    (实际上不推荐)

    【讨论】:

    • 谢谢。这是解决问题的一种更简单的方法。我仍然想知道,我是否需要将Msg“转换”为Cmd Msg?如果我这样做了,我会怎么做?
    • @ChadGilbert:您能否详细说明一下为什么您不推荐第二种方法,即解雇新的Msg
    • 返回 Cmd 将导致 Elm 架构生命周期的另一个循环,因此您实际上只是在花费额外的 CPU 周期,如果它只是为了触发另一个 Msg,您不需要浪费。可能有你想要强制另一个事件循环的原因(如动画或其他视图更新,但即使这些也需要额外的代码)。在大多数情况下,强制一个不必要的Cmd,IMO,感觉就像它错过了update 函数作为函数的底层性质,并且误解了事件周期。
    • 是否有可能通过MorePlease 消息传递一些参数?
    • 是的,任何产生Msg 的东西都可以使用。例如。 Cmd.map (always (SomethingElse param1 param2)) Cmd.none
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    相关资源
    最近更新 更多