Elm Language
ポート(JS interop)
サーチ…
構文
- Elm(受信):ポートfunctionName:(値 - > msg) - > Sub msg
- JS(送信):app.ports.functionName.send(値)
- Elm(送信):port functionName:args - > Cmd msg
- JS(受信):app.ports.functionName.subscribe(function(args){...});
備考
これらの例の理解を助けるために、 The Elm Guideの http://guide.elm-lang.org/interop/javascript.htmlを参照してください 。
概要
ポートを使用しているモジュールは、そのモジュール定義にportキーワードを持つ必要がありport 。
port module Main exposing (..)
サブスクリプションやコマンドの使用を許可していないため、 Html.App.beginnerProgramでポートを使用することはできません。
ポートは、 Html.App.programまたはHtml.App.programWithFlags更新ループに統合されています。
注意
programとprogramWithFlagsニレ0.18では、パッケージの内側にあるHtml代わりにHtml.App 。
送信
送信ポートはコマンドとして使用され、 update機能から返されます。
エルムサイド
送信ポートを定義する:
port output : () -> Cmd msg
この例では、JavaScript側でサブスクリプションをトリガーするために空のタプルを送信します。
これを行うには、Elmからの送信データを送信するためのコマンドを取得するために、空のタプルを引数としてoutput関数を適用する必要があります。
update msg model =
case msg of
TriggerOutgoing data ->
( model, output () )
JavaScript側
アプリケーションを初期化する:
var root = document.body;
var app = Elm.Main.embed(root);
対応する名前のポートにサブスクライブします。
app.ports.output.subscribe(function () {
alert('Outgoing message from Elm!');
});
注意
0.17.0から、JavaScriptへの即時発信メッセージは、 initial状態からは効果がありません。
init : ( Model, Cmd Msg )
init =
( Model 0, output () ) -- Nothing will happen
以下の例の回避策を参照してください。
着信
JavaScriptからの着信データはサブスクリプションを経由しています。
エルムサイド
まず、次の構文を使用して、着信ポートを定義する必要があります。
port input : (Int -> msg) -> Sub msg
複数のサブスクリプションがある場合、 Sub.batchを使用できます。この例では、 input portへのサブスクリプションは1つだけinput port
subscriptions : Model -> Sub Msg
subscriptions model =
input Get
次に、 Html.program subscriptionsを渡す必要があります:
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
JavaScript側
アプリケーションを初期化する:
var root = document.body;
var app = Elm.Main.embed(root);
メッセージをElmに送ってください:
var counter = 0;
document.body.addEventListener('click', function () {
counter++;
app.ports.input.send(counter);
});
注意
0.17.0は直ちにapp.ports.input.send(counter);注意してくださいapp.ports.input.send(counter);アプリの初期化後は効果がありません!
Html.programWithFlagsを使用して、起動時に必要なすべてのデータをFlagsとしてHtml.programWithFlags
起動時に0.17.0で即時発信メッセージ
データを含むメッセージをJavaScriptに送信するには、 initからアクションをトリガーする必要があります。
init : ( Model, Cmd Msg )
init =
( Model 0, send SendOutgoing )
send : msg -> Cmd msg
send msg =
Task.perform identity identity (Task.succeed msg)
始める
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
まだelm-package install elm-lang/html --yesない場合は、 elm-lang/html elm-package install elm-lang/html --yes 。
elm-make Main.elm --yes --output elm.jsを使用してこのコードをコンパイルし、HTMLファイルで見つけます。
すべてがうまくいけば、 "No message"テキストが表示された状態でindex.htmlファイルを開くことができます。 3秒後にJSはメッセージを送信し、Elmはそれを取得し、モデルを変更し、応答を送信し、JSはそれを取得し、アラートをオープンします。