Recherche…


Syntaxe

  • Elm (reception): port functionName: (valeur -> msg) -> Sub msg
  • JS (envoi): app.ports.functionName.send (valeur)
  • Elm (Envoi): Port functionName: args -> Cmd msg
  • JS (réception): app.ports.functionName.subscribe (fonction (args) {...});

Remarques

Consultez http://guide.elm-lang.org/interop/javascript.html dans The Elm Guide pour vous aider à comprendre ces exemples.

Vue d'ensemble

Un module utilisant les ports doit avoir un mot-clé de port dans sa définition de module.

port module Main exposing (..)

Il est impossible d'utiliser les ports avec Html.App.beginnerProgram , car il ne permet pas d'utiliser les abonnements ou les commandes.

Les ports sont intégrés pour mettre à jour la boucle de Html.App.program ou Html.App.programWithFlags .

Remarque

program et programWithFlags dans elm 0.18 sont à l'intérieur du package Html au lieu de Html.App .

Sortant

Les ports sortants sont utilisés comme commandes, que vous renvoyez depuis votre fonction de update .

Côté orme

Définir le port sortant:

port output : () -> Cmd msg

Dans cet exemple, nous envoyons un Tuple vide pour déclencher un abonnement côté JavaScript.

Pour ce faire, nous devons appliquer output fonction de output avec un argument Tuple vide, afin d'obtenir une commande pour l'envoi des données sortantes d'Elm.

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

Côté JavaScript

Initialiser l'application:

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

Abonnez-vous à un port avec un nom correspondant:

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

Remarque

A partir de 0.17.0 , le message sortant immédiat à JavaScript de votre état initial n'aura aucun effet.

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

Voir la solution de contournement dans l'exemple ci-dessous.

Entrants

Les données entrantes de JavaScript passent par des abonnements.

Côté orme

Tout d'abord, nous devons définir un port entrant en utilisant la syntaxe suivante:

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

Nous pouvons utiliser Sub.batch si nous avons plusieurs abonnements, cet exemple ne contiendra qu'un seul abonnement au input port

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

Ensuite, vous devez transmettre les subscriptions à votre programme Html.program :

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

Côté JavaScript

Initialiser l'application:

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

Envoyer le message à Elm:

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

Remarque

S'il vous plaît noter que à partir de 0.17.0 le app.ports.input.send(counter); immédiat app.ports.input.send(counter); après l'application l'initialisation n'aura aucun effet!

Transmettez toutes les données requises pour le démarrage en tant que Html.programWithFlags aide de Html.programWithFlags

Message sortant immédiat au démarrage en 0.17.0

Pour envoyer un message immédiat contenant des données à JavaScript, vous devez déclencher une action à partir de votre init .

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


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

Commencer

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

Installez le paquet elm-lang/html si vous ne l'avez pas encore fait par elm-package install elm-lang/html --yes .

Compilez ce code en utilisant elm-make Main.elm --yes --output elm.js pour que le fichier HTML le trouve.

Si tout se passe bien, vous devriez pouvoir ouvrir le fichier index.html avec le texte "Aucun message" affiché. Après trois secondes, le JS envoie un message, Elm le reçoit, modifie son modèle, envoie une réponse, JS le reçoit et ouvre une alerte.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow