我正在使用端口将对象从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 }
类型的参数
答案 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
最终成为应用程序模型最新版本的信号,然后您可以将其映射到Html
或Graphics.Element
或其他信号您希望再次使用Signal.map
来生成一些对应用程序中的更新做出反应的用户界面。