Elm Language
Ports (JS-Interop)
Suche…
Syntax
- Elm (Empfangen): Portfunktionsname: (Wert -> msg) -> Sub msg
- JS (Senden): app.ports.functionName.send (Wert)
- Ulme (Senden): Portfunktionsname: args -> Cmd msg
- JS (Empfangen): app.ports.functionName.subscribe (function (args) {...});
Bemerkungen
Informationen zum Verständnis dieser Beispiele finden Sie im The Elm Guide unter http://guide.elm-lang.org/interop/javascript.html .
Überblick
Ein Modul, das Ports verwendet, sollte das Schlüsselwort port in seiner Moduldefinition enthalten.
port module Main exposing (..)
Es ist nicht möglich, Ports mit Html.App.beginnerProgram , da Abonnements oder Befehle nicht verwendet werden können.
Ports sind in die Aktualisierungsschleife von Html.App.program oder Html.App.programWithFlags .
Hinweis
program und programWithFlags in elm programWithFlags befinden sich im Paket Html anstelle von Html.App .
Ausgehend
Ausgehende Ports werden als Befehle verwendet, die Sie von Ihrer update .
Ulmenseite
Ausgangsport definieren:
port output : () -> Cmd msg
In diesem Beispiel senden wir ein leeres Tuple, um auf JavaScript-Seite ein Abonnement auszulösen.
Dazu müssen wir die output mit einem leeren Tupel als Argument anwenden, um einen Befehl zum Senden der ausgehenden Daten von Elm zu erhalten.
update msg model =
case msg of
TriggerOutgoing data ->
( model, output () )
JavaScript-Seite
Initialisieren Sie die Anwendung:
var root = document.body;
var app = Elm.Main.embed(root);
Abonnieren Sie einen Port mit einem entsprechenden Namen:
app.ports.output.subscribe(function () {
alert('Outgoing message from Elm!');
});
Hinweis
Ab 0.17.0 hat eine sofortige ausgehende Nachricht an JavaScript aus Ihrem initial Zustand keine Auswirkungen.
init : ( Model, Cmd Msg )
init =
( Model 0, output () ) -- Nothing will happen
Siehe im folgenden Beispiel die Problemumgehung.
Eingehend
Eingehende Daten von JavaScript werden über Abonnements geleitet.
Ulmenseite
Zunächst müssen wir einen eingehenden Port mit der folgenden Syntax definieren:
port input : (Int -> msg) -> Sub msg
Wir können verwenden Sub.batch wenn wir mehrere Abonnements haben, werden in diesem Beispiel enthalten nur ein Abonnement für input port - input port
subscriptions : Model -> Sub Msg
subscriptions model =
input Get
Dann müssen Sie die subscriptions an Ihr Html.program :
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
JavaScript-Seite
Initialisieren Sie die Anwendung:
var root = document.body;
var app = Elm.Main.embed(root);
Sende die Nachricht an Elm:
var counter = 0;
document.body.addEventListener('click', function () {
counter++;
app.ports.input.send(counter);
});
Hinweis
Bitte beachten Sie, dass ab 0.17.0 die sofortigen app.ports.input.send(counter); nach der App-Initialisierung hat keine Wirkung!
Html.programWithFlags alle für den Start erforderlichen Daten als Flags mit Html.programWithFlags
Sofort ausgehende Nachricht beim Start in 0.17.0
Um eine sofortige Nachricht mit Daten an JavaScript zu senden, müssen Sie eine Aktion von Ihrer init auslösen.
init : ( Model, Cmd Msg )
init =
( Model 0, send SendOutgoing )
send : msg -> Cmd msg
send msg =
Task.perform identity identity (Task.succeed msg)
Loslegen
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
Installieren Sie das Paket elm-lang/html , wenn Sie es noch nicht mit elm-package install elm-lang/html --yes .
Kompilieren Sie diesen Code mit elm-make Main.elm --yes --output elm.js damit die HTML-Datei ihn findet.
Wenn alles gut geht, sollten Sie die index.html Datei mit dem Text "No message" öffnen können. Nach drei Sekunden sendet der JS eine Nachricht, Elm erhält sie, ändert ihr Modell, sendet eine Antwort, JS erhält sie und öffnet eine Warnung.