Elm Language
Puertos (interoperabilidad JS)
Buscar..
Sintaxis
- Elm (recibir): puerto functionName: (value -> msg) -> Sub msg
- JS (envío): app.ports.functionName.send (valor)
- Elm (enviando): puerto functionName: args -> Cmd msg
- JS (recibiendo): app.ports.functionName.subscribe (function (args) {...});
Observaciones
Consulte http://guide.elm-lang.org/interop/javascript.html de The Elm Guide para ayudar a entender estos ejemplos.
Visión general
Un módulo, que utiliza puertos, debe tener una palabra clave de port en su definición de módulo.
port module Main exposing (..)
Es imposible usar puertos con Html.App.beginnerProgram , ya que no permite el uso de suscripciones o comandos.
Los puertos están integrados para actualizar el bucle de Html.App.program o Html.App.programWithFlags .
Nota
program y programWithFlags en elm 0.18 están dentro del paquete Html lugar de Html.App .
Saliente
Los puertos salientes se utilizan como Comandos, que devuelve de su función de update .
Lado olmo
Definir puerto de salida:
port output : () -> Cmd msg
En este ejemplo, enviamos un Tuple vacío, solo para activar una suscripción en el lado de JavaScript.
Para hacerlo, tenemos que aplicar output función de output con un Tuple vacío como argumento, para obtener un comando para enviar los datos salientes de Elm.
update msg model =
case msg of
TriggerOutgoing data ->
( model, output () )
Lado de JavaScript
Inicializar la aplicación:
var root = document.body;
var app = Elm.Main.embed(root);
Suscríbete a un puerto con un nombre correspondiente:
app.ports.output.subscribe(function () {
alert('Outgoing message from Elm!');
});
Nota
A partir del 0.17.0 , el mensaje saliente inmediato a JavaScript desde su estado initial no tendrá efecto.
init : ( Model, Cmd Msg )
init =
( Model 0, output () ) -- Nothing will happen
Vea la solución en el siguiente ejemplo.
Entrante
Los datos entrantes de JavaScript están pasando por las suscripciones.
Lado olmo
Primero, necesitamos definir un puerto entrante, usando la siguiente sintaxis:
port input : (Int -> msg) -> Sub msg
Podemos usar Sub.batch si tenemos varias suscripciones, este ejemplo solo contendrá una suscripción al input port
subscriptions : Model -> Sub Msg
subscriptions model =
input Get
Luego tiene que pasar las subscriptions a su programa Html.program :
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
Lado de JavaScript
Inicializar la aplicación:
var root = document.body;
var app = Elm.Main.embed(root);
Envía el mensaje a Elm:
var counter = 0;
document.body.addEventListener('click', function () {
counter++;
app.ports.input.send(counter);
});
Nota
Tenga en cuenta que a partir del 0.17.0 el app.ports.input.send(counter); inmediato app.ports.input.send(counter); Después de la inicialización de la aplicación no tendrá ningún efecto!
Pase todos los datos necesarios para el inicio como indicadores que utilizan Html.programWithFlags
Mensaje saliente inmediato en el arranque en 0.17.0
Para enviar un mensaje inmediato con datos a JavaScript, debe activar una acción desde su init .
init : ( Model, Cmd Msg )
init =
( Model 0, send SendOutgoing )
send : msg -> Cmd msg
send msg =
Task.perform identity identity (Task.succeed msg)
Empezar
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
Instale el paquete elm-lang/html si aún no lo ha hecho con elm-package install elm-lang/html --yes .
Compile este código usando elm-make Main.elm --yes --output elm.js para que el archivo HTML lo encuentre.
Si todo va bien, debería poder abrir el archivo index.html con el texto "Sin mensaje" que se muestra. Después de tres segundos, JS envía un mensaje, Elm lo recibe, cambia su modelo, envía una respuesta, JS lo recibe y abre una alerta.