Поиск…


Синтаксис

  • Elm (получение): port functionName: (значение -> msg) -> Sub msg
  • JS (отправка): app.ports.functionName.send (значение)
  • Elm (отправка): port functionName: args -> Cmd msg
  • JS (получение): app.ports.functionName.subscribe (function (args) {...});

замечания

Проконсультируйтесь с http://guide.elm-lang.org/interop/javascript.html из руководства Elm, чтобы помочь понять эти примеры.

обзор

Модуль, который использует порты, должен иметь ключевое слово port в определении модуля.

port module Main exposing (..)

Невозможно использовать порты с Html.App.beginnerProgram , поскольку он не позволяет использовать Подписки или Команды.

Порты интегрированы в цикл обновления Html.App.program или Html.App.programWithFlags .

Заметка

program и programWithFlags в elm 0.18 находятся внутри пакета Html вместо Html.App .

исходящий

Исходящие порты используются в качестве команд, которые вы возвращаете из своей функции update .

Вяз

Определить исходящий порт:

port output : () -> Cmd msg

В этом примере мы отправляем пустой Tuple, чтобы вызвать подписку на стороне JavaScript.

Для этого нам нужно применить функцию output с пустым Tuple в качестве аргумента, чтобы получить команду для отправки исходящих данных из Elm.

update msg model =
    case msg of
        TriggerOutgoing data ->
            ( model, output () )

Сторона JavaScript

Инициализировать приложение:

var root = document.body;
var app = Elm.Main.embed(root);

Подпишитесь на порт с соответствующим именем:

app.ports.output.subscribe(function () {
    alert('Outgoing message from Elm!');
});

Заметка

Начиная с 0.17.0 , немедленное исходящее сообщение на JavaScript из вашего initial состояния не будет иметь никакого эффекта.

init : ( Model, Cmd Msg )
init =
    ( Model 0, output () ) -- Nothing will happen

См. Обходной путь в примере ниже.

вступающий

Входящие данные из JavaScript проходят через Подписки.

Вяз

Во-первых, нам нужно определить входящий порт, используя следующий синтаксис:

port input : (Int -> msg) -> Sub msg

Мы можем использовать Sub.batch если у нас есть несколько подписчиков, этот пример будет содержать только одну подписку на input port

subscriptions : Model -> Sub Msg
subscriptions model =
    input Get

Затем вам нужно передать subscriptions на свою Html.program :

main =
    Html.program
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

Сторона JavaScript

Инициализировать приложение:

var root = document.body;
var app = Elm.Main.embed(root);

Отправить сообщение для Elm:

var counter = 0;
        
document.body.addEventListener('click', function () {
    counter++;
    app.ports.input.send(counter);
});

Заметка

Обратите внимание, что с 0.17.0 сразу же app.ports.input.send(counter); после инициализации приложения не будет никакого эффекта!

Передайте все необходимые данные для запуска, как флаги, используя Html.programWithFlags

Немедленное исходящее сообщение при запуске в 0.17.0

Чтобы отправить немедленное сообщение с данными на JavaScript, вам необходимо вызвать действие из вашего init .

init : ( Model, Cmd Msg )
init =
    ( Model 0, send SendOutgoing )


send : msg -> Cmd msg
send msg =
    Task.perform identity identity (Task.succeed msg)

Начать

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Trying out ports</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="elm.js"></script>
    <script>
    
      var node = document.getElementById('app');
      var app = Elm.Main.embed(node);
      
      // subscribe to messages from Elm
      app.ports.toJs.subscribe(function(messageFromElm) {
        alert(messageFromElm);
        // we could send something back by
        // app.ports.fromJs.send('Hey, got your message! Sincerely, JS');
      });
      
      // wait three seconds and then send a message from JS to Elm
      setTimeout(function () {
        app.ports.fromJs.send('Hello from JS');
      }, 3000);
      
    </script>
  </body>
</html>

Main.elm

port module Main exposing (..)

import Html

port toJs : String -> Cmd msg
port fromJs : (String -> msg) -> Sub msg

main =
   Html.program
        { init = (Nothing, Cmd.none) -- our model will be the latest message from JS (or Nothing for 'no message yet')
        , update = update
        , view = view
        , subscriptions = subscriptions
        }

type Msg
    = GotMessageFromJs String

update msg model =
    case msg of
        GotMessageFromJs message ->
            (Just message, toJs "Hello from Elm")

view model =
    case model of
        Nothing ->
            Html.text "No message from JS yet :("
        Just message ->
            Html.text ("Last message from JS: " ++ message)

subscriptions model =
    fromJs GotMessageFromJs

Установите пакет elm-lang/html , если вы еще не elm-package install elm-lang/html --yes .

Скомпилируйте этот код, используя elm-make Main.elm --yes --output elm.js чтобы файл HTML нашел его.

Если все будет хорошо, вы должны открыть файл index.html с отображаемым текстом «Нет сообщения». Через три секунды JS отправляет сообщение, Elm получает его, изменяет свою модель, отправляет ответ, JS получает его и открывает предупреждение.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow