Elm Language
Порты (JS interop)
Поиск…
Синтаксис
- 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 получает его и открывает предупреждение.