榆树 - 根据信号中的值更新模型

时间:2015-12-29 06:16:57

标签: signals elm

我正在使用端口将对象从javascript传递给elm,我想根据从JS收到的值更新我的模型。继承我的代码:

    type alias Model = { x: String, y: String }
    type Action = Received { x: String, y: String }
    update : Action -> Model -> Model
    update action model =
        case action of
            Received rec -> { model | x = rec.x, y = rec.y }

    port rec : Signal { x: String, y: String }
    result = Signal.map update (Received rec)

但是,我在最后一行收到类型不匹配编译器错误,说update在收到Signal { x: String, y: String }

时收到{ x: String, y: String }类型的参数

1 个答案:

答案 0 :(得分:1)

所以看起来你想要做的就是从你的端口的传入记录信号转到模型当前状态的信号。评论中提到foldp,它会发挥作用,所以我一定会解决它。为了从您的端口​​获取当前模型状态的信号,这就是您的代码的样子:

initialModel : Model
initialModel =
  { x = "0"
  , y = "0"
  }

result : Signal Model
result =
  rec
    |> Signal.map Received
    |> Signal.foldp update initialModel

现在让我们一步一步。

initialModel : Model
initialModel =
  { x = "0"
  , y = "0"
  }

通过此分配,我们设置了一个初始状态,可以从中继续。无论初始值是否与您的程序相关,Elm的信号必须始终具有初始值。如果您不关心初始模型是什么,您可以将记录的字段指定为您喜欢的任何字段。

result : Signal Model
result =
  rec
    |> Signal.map Received
    -- ...

在这里,我们使用Signal.map从您的端口​​的{ x : String, y : String }记录转到Action的信号,即Recieved操作。所以在这个阶段我们有一个Signal Action

|> Signal.foldp update initialModel

在最后一步中,我们从上一步中获取Signal Action并将其折叠到包含Signal.foldp的上一个模型中。第一个参数是一个函数,它接受某个类型a表示来自另一个信号的传入新值(在这种情况下它是我们的Signal Action),以及我们状态的最后一个可用值(即initialModel一开始,然后是update前进的最后一个返回值,并返回下一个状态。这就是在Elm应用程序中获取任何有状态的方式。

result最终成为应用程序模型最新版本的信号,然后您可以将其映射到HtmlGraphics.Element或其他信号您希望再次使用Signal.map来生成一些对应用程序中的更新做出反应的用户界面。

相关问题