Elm Language
Porte (interpolazione JS)
Ricerca…
Sintassi
- Elm (ricezione): porta functionName: (valore -> msg) -> Sott msg
- JS (invio): app.ports.functionName.send (valore)
- Elm (invio): port functionName: args -> Cmd msg
- JS (ricezione): app.ports.functionName.subscribe (function (args) {...});
Osservazioni
Consulta http://guide.elm-lang.org/interop/javascript.html dalla Guida di Elm per aiutare a comprendere questi esempi.
Panoramica
Un modulo, che usa le porte dovrebbe avere la parola chiave port nella sua definizione del modulo.
port module Main exposing (..)
È impossibile utilizzare le porte con Html.App.beginnerProgram , poiché non consente l'utilizzo di abbonamenti o comandi.
Le porte sono integrate per aggiornare il ciclo di Html.App.program o Html.App.programWithFlags .
Nota
program e programWithFlags a Elm 0.18 sono all'interno della confezione Html anziché Html.App .
Estroverso
Le porte in uscita vengono utilizzate come comandi, che vengono restituiti dalla funzione di update .
Lato olmo
Definire il porto in uscita:
port output : () -> Cmd msg
In questo esempio inviamo una Tupla vuota, solo per attivare un abbonamento sul lato JavaScript.
Per fare ciò, dobbiamo applicare output funzione di output con una Tupla vuota come argomento, per ottenere un comando per l'invio dei dati in uscita da Elm.
update msg model =
case msg of
TriggerOutgoing data ->
( model, output () )
Lato JavaScript
Inizializza l'applicazione:
var root = document.body;
var app = Elm.Main.embed(root);
Iscriviti ad una porta con un nome corrispondente:
app.ports.output.subscribe(function () {
alert('Outgoing message from Elm!');
});
Nota
A partire da 0.17.0 , il messaggio in uscita immediato su JavaScript dallo stato initial non avrà alcun effetto.
init : ( Model, Cmd Msg )
init =
( Model 0, output () ) -- Nothing will happen
Vedere la soluzione alternativa nell'esempio seguente.
in arrivo
I dati in arrivo da JavaScript stanno attraversando le iscrizioni.
Lato olmo
Innanzitutto, dobbiamo definire una porta in entrata, usando la seguente sintassi:
port input : (Int -> msg) -> Sub msg
Possiamo utilizzare Sub.batch se disponiamo di più abbonamenti, questo esempio conterrà solo un abbonamento alla input port
subscriptions : Model -> Sub Msg
subscriptions model =
input Get
Quindi devi passare gli subscriptions al tuo Html.program :
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
Lato JavaScript
Inizializza l'applicazione:
var root = document.body;
var app = Elm.Main.embed(root);
Invia il messaggio a Elm:
var counter = 0;
document.body.addEventListener('click', function () {
counter++;
app.ports.input.send(counter);
});
Nota
Si noti che a partire da 0.17.0 l' app.ports.input.send(counter); immediata app.ports.input.send(counter); dopo l'inizializzazione dell'app non avrà alcun effetto!
Passa tutti i dati richiesti per l'avvio come Flags usando Html.programWithFlags
Messaggio immediato in uscita all'avvio in 0.17.0
Per inviare un messaggio immediato con dati a JavaScript, devi attivare un'azione dal tuo init .
init : ( Model, Cmd Msg )
init =
( Model 0, send SendOutgoing )
send : msg -> Cmd msg
send msg =
Task.perform identity identity (Task.succeed msg)
Iniziare
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
Installa il pacchetto elm-lang/html se non lo hai ancora elm-package install elm-lang/html --yes .
Compilare questo codice usando elm-make Main.elm --yes --output elm.js modo che il file HTML lo trovi.
Se tutto va bene, dovresti essere in grado di aprire il file index.html con il messaggio "Nessun messaggio" visualizzato. Dopo tre secondi, il JS invia un messaggio, Elm lo riceve, cambia il suo modello, invia una risposta, JS lo riceve e apre un avviso.