我希望将Elm与Javascript库集成,使Elm能够动态创建“单元格”(html divs),并向Javascript提供它们的id以便执行自定义操作。我想要实现的顺序是:
问题在于另一侧的Javascript。
- Elm创建一个单元格(并分配id)
- 发送带有id的消息到端口
- Javascript接收消息并执行其操作
port onCellAdded : CellID -> Cmd msg
update : Msg -> Model -> (Model, Cmd Msg)
update message ({cells} as model) =
case message of
Push ->
let
uid = List.length cells
in
({ model
| cells = [uid] ++ cells
}, onCellAdded uid)
问题在于另一侧的Javascript。
var container = document.getElementById('app');
var demoApp = Elm.RenderDemo.embed(container);
demoApp.ports.onCellAdded.subscribe(function(cellID) {
if(document.getElementById('cell:' + cellID) === null) { window.alert("Cannot find cell " + cellID) }
});
抱怨说找不到这样的id。显然视图尚未呈现。
因此,我向Elm应用程序添加了另一个状态(OnCellAdded
),希望流程如下:
- Elm创建单元格(在Push上)并请求(
Task.perform
)异步任务OnCellAdded
- 这里渲染视图
OnCellAdded
被调用,并将带有id的消息发送到端口- Javascript接收消息并执行其操作
实现看起来像这样(diff)(full source):
update message ({cells} as model) =
case message of
Push ->
let
uid = List.length cells
in
({ model
| cells = [uid] ++ cells
}, msgToCmd (OnCellAdded uid))
OnCellAdded counter ->
(model, onCellAdded counter)
msgToCmd : msg -> Cmd msg
msgToCmd msg =
Task.perform identity identity (Task.succeed msg)
但是仍然会在 Push
后立即处理 OnCellAdded
,而模型之间不会被渲染。
我最后的尝试是使用 Update.andThen
(差异) (完整源代码)
Push ->
let
uid = List.length cells
in
({ model
| cells = [uid] ++ cells
}, Cmd.none)
|> Update.andThen update (OnCellAdded uid)
仍然不起作用。我需要帮助。