リムでELMポートを書く- 0.3
19520 ワード
これは、前の記事への更新は、2010年の破壊的変化に続きます
最近、NPMパッケージと呼ばれるパッケージを公開しましたres-elm そして、プロジェクトのカップルで生産にそれを入れてください.それは簡単にReadMeによって文書化されます、しかし、私はそれが完全なポストに値すると思います.このポストは、どのようにElmを使用してELM 0.19プロジェクトの両方のポートを設定する方法を歩いていきます.
最終製品は、最小限に再現性があり、理解しやすいものであり、必ずしも有用ではない.この場合、私は、この非常に小さな図書館の特徴を示す最高のページが非常に小さいウェブアプリであると思います.あなたはそのようなアプリを見つけることができますin this live demo .
つのテキストボックスを再生する瞬間を取る.最初の1つはrescriptlandに住んでいるが、その入力イベントでは、rescriptは、elmアプリにその内容を送信します.2番目はelmlandに住んでいますが、その入力イベントでは、入力を別のポートを通してリスクリプトスクリプトに送ります.結果は常に一致する2つのテキストボックスです.
通常、私はエルムのアプリの外に住んでいるテキストボックスを持っていることはありません-私はエルムに全体のビューの制御を与えるだろうが、それはアプリケーションが代わりにindexeddbリポジトリのようなものを持っていることを想像しやすいですChicago area COVID-19 tracker , いくつかのJSONデータへのHTTP呼び出し.
基本的なELMプロジェクトを書く方法についての詳細な説明は、この種のポストについての範囲外ですが、完全性のためにここにいくつかのELMコードが欲しいです.
つの基本的なメッセージから始めましょう
MSGエルム
私も、このELMアプリの2つのポートが欲しい、再びこのelmアプリのデータの双方向フローを表します.
ポート.エルム
メイン.エルム
次に、新しいrescriptプロジェクトを初期化してくださいres-elm そして、
最後にインデックスを開きます.resファイルを開き、モジュールを公開します.
次に、ポートを囲む論理を定義します.これらの関数からポートを作成します.
このコードを詳細に説明するのはこのポストのスコープ外です.基本的に、私がしていることは、入力の値を取得したり設定したりするのに必要な基本的なDOM機能のバインディングを定義することです
ELMアプリを初期化すると、各フィールドは私たちのELMアプリのポートを表すレコードの形式で型パラメータが必要です.The
このアプリはちょうど2つのポートで単純なケースですが、私はこのタイプのモジュールを定義する自由を取るつもりです.
今我々は我々のタイプを持って、我々は我々のアプリを得ることができます.これは、JavaScriptのELM(v 0.19)ポートを書いている誰にも身近に見えるべきです.The
これはたくさんのように見えます、しかし、我々がしているすべては
The
今、すべてのそれを残して私たちのHTMLマークアップで一緒にすべてを置くことです.
それは我々のプロジェクトを終了!再び、完成した例を見つけることができますon my demo site , and full source here . あなたが質問をするならば私に知らせてください!
res-elm
結合.要するにinit
関数が壊れたinit
and initWithOptions
ELMの初期化フラグとELMのWebアプリケーションを許可する.最近、NPMパッケージと呼ばれるパッケージを公開しましたres-elm そして、プロジェクトのカップルで生産にそれを入れてください.それは簡単にReadMeによって文書化されます、しかし、私はそれが完全なポストに値すると思います.このポストは、どのようにElmを使用してELM 0.19プロジェクトの両方のポートを設定する方法を歩いていきます.
目標:ポートを通してRScriptとELMの間の共有制御
最終製品は、最小限に再現性があり、理解しやすいものであり、必ずしも有用ではない.この場合、私は、この非常に小さな図書館の特徴を示す最高のページが非常に小さいウェブアプリであると思います.あなたはそのようなアプリを見つけることができますin this live demo .
つのテキストボックスを再生する瞬間を取る.最初の1つはrescriptlandに住んでいるが、その入力イベントでは、rescriptは、elmアプリにその内容を送信します.2番目はelmlandに住んでいますが、その入力イベントでは、入力を別のポートを通してリスクリプトスクリプトに送ります.結果は常に一致する2つのテキストボックスです.
通常、私はエルムのアプリの外に住んでいるテキストボックスを持っていることはありません-私はエルムに全体のビューの制御を与えるだろうが、それはアプリケーションが代わりにindexeddbリポジトリのようなものを持っていることを想像しやすいですChicago area COVID-19 tracker , いくつかのJSONデータへのHTTP呼び出し.
ELMセットアップ
基本的なELMプロジェクトを書く方法についての詳細な説明は、この種のポストについての範囲外ですが、完全性のためにここにいくつかのELMコードが欲しいです.
つの基本的なメッセージから始めましょう
SendString
and UpdateString
これは、アプリケーションの内外に情報の流れの2つの方向を表します.MSGエルム
module Msg exposing (..)
type Msg = SendString String | UpdateString String
ELMポートに慣れているなら、ELMポートのJSONエンコード/デコードに慣れているはずです.これは私が実証しようとしているものの範囲外であるので、ここのストリングはうまくいくでしょう、しかし、JSONを安全に解析することは最高の実行です、そして、あなたは複雑なデータ型のためにそれを必要とします.私も、このELMアプリの2つのポートが欲しい、再びこのelmアプリのデータの双方向フローを表します.
ポート.エルム
port module Ports exposing (..)
port toReScript : String -> Cmd msg
port toElm : (String -> msg) -> Sub msg
そして今、フクロウの残りの部分を描画します.メイン.エルム
module Main exposing (main)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode
import Models exposing (Model)
import Msg exposing (..)
import Ports
main : Program () Model Msg
main = Browser.element
{ init = init
, subscriptions = subscriptions
, update = update
, view = view
}
------------------------
init : () -> (Model, Cmd Msg)
init _ = ( Models.init
, Cmd.none
)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch [ Ports.toElm UpdateString --subscribe to incoming string
]
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
SendString str -> { model | str = str }
|> \m -> ( m, Ports.toReScript m.str ) --call outgoing port
UpdateString val -> { model | str = val }
|> \m -> (m, Cmd.none)
view : Model -> Html Msg
view model =
div [ class "elm-parent" ]
[ h2 [ class "h2" ] [ text "Controlled by Elm" ]
, input [ placeholder "enter some text"
, type_ "text"
, onInput SendString
, value model.str
] []
]
再び、私はこれのあらゆるインチを通過するつもりでありません--私はちょうど参考のためにここにそれを望みます.ご覧のように、メッセージはupdate
関数とonInput
イベントは、着信ポートはsubscriptions
.プロジェクトのセットアップ
次に、新しいrescriptプロジェクトを初期化してくださいres-elm そして、
bs-dependencies
.最後にインデックスを開きます.resファイルを開き、モジュールを公開します.
open Elm;
完全に
次に、ポートを囲む論理を定義します.これらの関数からポートを作成します.
このコードを詳細に説明するのはこのポストのスコープ外です.基本的に、私がしていることは、入力の値を取得したり設定したりするのに必要な基本的なDOM機能のバインディングを定義することです
target
JavaScriptからevent
./* setup: simple JS dom interop */
@val @scope("document")
external getElementById: string => Dom.element = "getElementById"
@get external getValue: Dom.element => string = "value"
@set external setValue: (Dom.element, string) => unit = "value"
@set external setOnInput: (Dom.element, Dom.event => unit) => unit = "oninput"
@get external getTarget: Dom.event => Dom.element = "target"
/* get input element */
let inputReScript: Dom.element = getElementById("input-rescript")
レコードをフィールドとして宣言する
ELMアプリを初期化すると、各フィールドは私たちのELMアプリのポートを表すレコードの形式で型パラメータが必要です.The
res-elm
パッケージは2つのタイプが含まれますElm.sendable<'t>
and Elm.subscribable<'t>
我々はelmアプリに情報を送信し、それから情報を購読することができます.このアプリはちょうど2つのポートで単純なケースですが、私はこのタイプのモジュールを定義する自由を取るつもりです.
module Ports = {
type t = {
toElm: Elm.sendable<string>,
toReScript: Elm.subscribable<string>
};
};
ELMアプリへのリファレンスを取得する
今我々は我々のタイプを持って、我々は我々のアプリを得ることができます.これは、JavaScriptのELM(v 0.19)ポートを書いている誰にも身近に見えるべきです.The
init
関数は一つのフィールドを持つレコードをとるnode
活字Dom.element
./* get app */
let app: Elm.app<Ports.t> =
Elm.Main.init({ node: Some(getElementById("elm-target")),
flags: None
});
結果はElm.app
それは私たちのポートへのアクセスを与えるので、それらを使用しましょう.イベントの配線
これはたくさんのように見えます、しかし、我々がしているすべては
Dom.element
名前inputReScript
と設定oninput
aの関数へのイベントDom.event
.The
app
早めにメンバーが来たports
と同じようにElm
パッケージはsend
バインドするsend
event.target.value
, JavaScriptのように.inputReScript
-> setOnInput(event => app.ports.toElm
-> Elm.send(event -> getTarget -> getValue));
この次のいずれかを少し簡単に従うことです.ここでは、私はsubscribe
値の設定inputReScript
我々のELMアプリがポートを通して値を送るときはいつでも.app.ports.toReScript -> Elm.subscribe(str => setValue(inputReScript, str));
インデックスを取得するためにコンパイルします.ビーエス.jsHTMLマークアップにまとめます
今、すべてのそれを残して私たちのHTMLマークアップで一緒にすべてを置くことです.
...
<div class="div-rescript-demo">
<h2 class="h2">Controlled by ReScript</h2>
<input class="input" id="input-rescript"
placeholder="enter some text" type="text" />
</div>
<div id="elm-target"></div>
</div><!--end container div-->
<script src="scripts/elm/index.js"></script>
<script src="scripts/rescript/src/Index.bs.js" type="module"></script>
これは私たちのアプリを期待しているすべてを与えます:1“入力スクリプト”テキストボックス、2“elmターゲット”div、3)スクリプトへの参照.それは我々のプロジェクトを終了!再び、完成した例を見つけることができますon my demo site , and full source here . あなたが質問をするならば私に知らせてください!
Reference
この問題について(リムでELMポートを書く- 0.3), 我々は、より多くの情報をここで見つけました https://dev.to/webbureaucrat/writing-elm-ports-in-rescript-03-196bテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol