首页 > 解决方案 > 如何使用 Elmish 和 Fable 将参数从 html 页面传递到编译的 js 应用程序

问题描述

在 elm 中,您可以将标志传递给 elm 应用程序,如下所示:

网页/JS

  <div id="elm"></div>
  <script>
var app = Elm.Main.init({
  node: document.getElementById('elm'),
  flags: Date.now()
});
  </script>

然后 elm 应用程序在 init 上获取参数:

init : Int -> ( Model, Cmd Msg )
init currentTime =
  ...

我已经阅读了寓言文档,对我来说尚不清楚如何实现同样的目标。

我看到有一个选项 Program.runWith 可以在 init 函数上发送参数,但我找不到文档,也无法从编译的 javascript 中看到我应该如何从 html 文件调用主函数。

对于寓言,我希望能够在 html 文件中执行类似的操作,但不确定“Program.Run ..”是什么:

<body>
    <div id="elmish-app" class="elmish-app"></div>
    <script src="bundle.js"></script>
    <script>
        Program.Run({time: Date.now()});
    </script>
</body>

谢谢

标签: ffifable-f#elmish

解决方案


创建 Elmish 时Program,您可以使用|> Program.runWith它来传递初始参数。

type Model =
    { Value : string }

let init (initial : string) = { Value = initial }, Cmd.none

Program.mkProgram init update view
|> Program.withReact "elmish-app"
|> Program.runWith "My initial value"

请注意,initialininit是一个字符串,因为它接收 的参数Program.runWith

为了公开 API,在您的浏览器中,hacky方法是执行以下操作:

open Fable.Core.JsInterop

let private startApplication arg =
    Program.mkProgram init update view
    |> Program.withReact "elmish-app"
    |> Program.runWith arg

Fable.Import.Browser.window?startApplication <- startApplication

startApplication因此,您要在全局范围内设置注册函数window

更简洁的解决方案是使用 configurewebpack以使其生成一个库并在window范围内为您注册它。

在您的 webpack.config.js 中,您的输出节点应如下所示:

    output: {
        path: resolve('./output'),
        filename: '[name].js',
        libraryTarget: 'var',
        library: 'Program'
    },

然后在您的代码中使用一个接口来公开一个 JavaScript 友好的 API:

type MyApp =
    abstract Run : string -> unit

let api =
    { new MyApp with
        member __.Run arg = startApplication arg
    }

现在您可以使用 JavaScript 从 JavaScript 调用它Program.api.Run("initial value")


推荐阅读