Sök…


Syntax

  • Elm (mottagande): portfunktion Namn: (värde -> msg) -> Sub msg
  • JS (skicka): app.ports.functionName.send (värde)
  • Elm (sänder): portfunktion Namn: args -> Cmd msg
  • JS (mottagande): app.ports.functionName.subscribe (funktion (args) {...});

Anmärkningar

Se http://guide.elm-lang.org/interop/javascript.html från Elm Guide för att hjälpa till att förstå dessa exempel.

Översikt

En modul, som använder hamnar ska ha port nyckelordet i den definition modul.

port module Main exposing (..)

Det är omöjligt att använda portar med Html.App.beginnerProgram , eftersom det inte tillåter att använda prenumerationer eller kommandon.

Portar är integrerade i för att uppdatera loopen av Html.App.program eller Html.App.programWithFlags .

Notera

program och programWithFlags i programWithFlags 0,18 finns i paketet Html istället för Html.App .

Utgående

Utgående portar används som kommandon som du kommer tillbaka från din update .

Elm sida

Definiera utgående port:

port output : () -> Cmd msg

I det här exemplet skickar vi en tom Tuple, bara för att utlösa ett prenumeration på JavaScript-sidan.

För att göra det måste vi tillämpa output med en tom Tuple som argument för att få ett kommando för att skicka utgående data från Elm.

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

JavaScript-sida

Initiera applikationen:

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

Prenumerera på en port med motsvarande namn:

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

Notera

Från 0.17.0 har omedelbart utgående meddelande till JavaScript från ditt initial tillstånd ingen effekt.

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

Se lösningen i exemplet nedan.

Inkommande

Inkommande data från JavaScript går via prenumerationer.

Elm sida

Först måste vi definiera en inkommande port med följande syntax:

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

Vi kan använda Sub.batch om vi har flera prenumerationer, det här exemplet kommer bara att innehålla ett prenumeration till input port

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

Sedan måste du skicka subscriptions till ditt Html.program :

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

JavaScript-sida

Initiera applikationen:

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

Skicka meddelandet till Elm:

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

Notera

Observera att från och med 0.17.0 den omedelbara app.ports.input.send(counter); efter appinitiering har ingen effekt!

Vidarebefordra alla nödvändiga data för uppstarten som flaggor med Html.programWithFlags

Omedelbart utgående meddelande vid start i 0.17.0

För att skicka ett omedelbart meddelande med data till JavaScript måste du utlösa en åtgärd från din init .

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


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

Komma igång

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

Installera paketet elm-lang/html om du ännu inte har elm-package install elm-lang/html --yes .

Kompilera denna kod med elm-make Main.elm --yes --output elm.js så att HTML-filen hittar den.

Om allt går bra, bör du kunna öppna filen index.html med texten "Inget meddelande". Efter tre sekunder skickar JS ett meddelande, Elm får det, byter modell, skickar ett svar, JS får det och öppnar en varning.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow