Как передать аргументы со страницы 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, и, вероятно, есть лучший подход.

[Просто хочу выделить для большей ясности, что они будут частью Исходной модели]

Другие вопросы по тегам