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.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow