Как передать аргументы со страницы html в скомпилированное приложение js, используя Elmish с Fable
В elm вы можете передать флаг приложению elm следующим образом:
HTML / 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-файла.
С помощью fable я хочу иметь возможность сделать что-то подобное в 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>
Спасибо
0 ответов
При создании вашего 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"
Обратите внимание, что initial
в init
является строкой, потому что она получает аргумент 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
,
Более чистым решением является использование конфигурации webpack
чтобы он сгенерировал библиотеку и зарегистрировал ее для вас в 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, используя Program.api.Run("initial value")
Просто основываясь на предыдущем ответе Максима Мангеля, я выбрал хакерский подход, но немного адаптировал его, чтобы использовать локальное хранилище. Я поделюсь этим, это альтернатива для всех, кому нужно найти способ передать аргументы в приложение Fable-Elmish, которые устанавливаются / собираются до начала.
В App.fs (последний запущенный / скомпилированный файл):
let initialArgs = {
Sender = Browser.Dom.window.localStorage.getItem("Sender")
HubConnectionURI = Browser.Dom.window.localStorage.getItem("ServiceURI")}
let startApplication args =
Program.mkSimple init update view
|> Program.withReactSynchronous "elmish-app"
|> Program.withSubscription Subscription.hubConnection
|> Program.withConsoleTrace
|> Program.runWith args
do startApplication initialArgs
Это извлекается из значений локального хранилища, установленных в браузере до инициализации приложения, поэтому вы можете установить их в JS, но при желании.
в index.html:
<body>
<div id="elmish-app" class="elmish-app"></div>
<script>
window.localStorage.setItem('Sender', 'Chairman Meow')
window.localStorage.setItem('ServiceURI', 'http://localhost:7071')
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.3/signalr.min.js"></script>
<script src="bundle.js"></script>
</body>
Вы, конечно, можете адаптировать это, но хотите использовать значения / переменные, которые установлены в локальном хранилище. Мне нужны были эти "динамические" начальные аргументы для параметризации Подписки, которую я хочу запустить при запуске программы, и я использую их для демонстрации, над которой я работаю, для использования SignalR в Fable-Elmish, и я, вероятно, адаптирую это, чтобы запрашивать это при загрузке страницы.
Однако дело здесь в том, что вы можете делать все, что хотите, чтобы получить значения, если они установлены в локальном хранилище до запуска приложения! Я считаю это относительно "чистым хаком", но я все еще новичок в Fable-Elmish, и, вероятно, есть лучший подход.
[Просто хочу выделить для большей ясности, что они будут частью Исходной модели]