如何在elm-app中使用Ports?附elm-live原生配置实现示例
在elm-app中配置Elm Ports的实操指南
嘿,我刚好折腾过在elm-app里配置Ports,给你一步步拆解下具体操作——毕竟它和你之前用的原生elm-live配置确实有不少差异:
第一步:在Elm代码里定义Ports
首先得在你的Main.elm里把需要的Port定义好,比如你之前用到的storeSession,如果需要从JS那边获取session,也可以加上接收用的Port:
port module Main exposing (main) -- 定义向JS发送session的Port port storeSession : String -> Cmd msg -- 可选:定义从JS接收session的Port port getSession : (String -> msg) -> Sub msg -- 你的核心Elm代码 main = Browser.element { init = init , view = view , update = update , subscriptions = subscriptions } -- 初始化函数,接收从JS传过来的flags(也就是localStorage里的session) init : Maybe String -> (Model, Cmd Msg) init maybeSession = ( initialModel maybeSession , Cmd.none ) -- 可选:订阅getSession的消息 subscriptions : Model -> Sub Msg subscriptions model = getSession GotSession
第二步:修改public/index.html里的JS逻辑
elm-app项目的index.html在public文件夹下,你需要在默认的Elm加载脚本后面,加上Port的交互代码:
<body> <noscript>您需要启用JavaScript才能运行此应用。</noscript> <div id="root"></div> <!-- 这是elm-app默认生成的加载脚本,别删! --> <script src="main.js"></script> <!-- 下面是我们的Port处理逻辑 --> <script> window.addEventListener("load", function(event) { // 重点:elm-app里用init挂载,不是fullscreen! var app = Elm.Main.init({ node: document.getElementById('root'), flags: localStorage.session || null }); // 监听Elm发来的storeSession指令,把session存到localStorage app.ports.storeSession.subscribe(function(session) { localStorage.session = session; }); // 可选:如果需要主动给Elm传session,解开下面这行 // app.ports.getSession.send(localStorage.session || null); }); </script> </body>
几个要注意的坑
- 挂载方式差异:原生elm-live里你用的是
Elm.Main.fullscreen(),但在elm-app里必须用Elm.Main.init({ node: ... })指定挂载节点,不然Port会直接失效。 - 脚本顺序:自定义的JS代码一定要放在
main.js之后,不然会找不到Elm.Main对象哦。 - Flags传递:把localStorage的session传给Elm的逻辑,要放在
init的flags字段里,和你之前的逻辑保持一致就好。
这样配置完,你的Elm应用就能和JS正常通过Ports交互啦~
内容的提问来源于stack exchange,提问作者Mark Karavan
相关产品推荐
相关产品推荐

