リムでELMポートを書く
20039 ワード
これはポストです.rebrand 前の投稿に更新してください」How to Write Elm Ports in ReasonML .「古い構文に慣れていない人々がまだそれを読むことができるように、私は新しいリスクリプション構文でパッケージを書き直しました.
最近、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コードが欲しいです.
つの基本的なメッセージから始めましょう
MSGエルム
私も、このELMアプリの2つのポートが欲しい、再びこのelmアプリのデータの双方向フローを表します.
ポート.エルム
メイン.エルム
プロジェクトのセットアップ
次に、新しいrescriptプロジェクトを初期化してくださいres-elm そして、
最後にインデックスを開きます.resファイルを開き、モジュールを公開します.
完全に
次に、ポートを囲む論理を定義します.これらの関数からポートを作成します.
このコードを詳細に説明するのはこのポストのスコープ外です.基本的に、私がしていることは、入力の値を取得したり設定したりするのに必要な基本的なDOM機能のバインディングを定義することです
レコードをフィールドとして宣言する
ELMアプリを初期化すると、各フィールドは私たちのELMアプリのポートを表すレコードの形式で型パラメータが必要です.The
このアプリはちょうど2つのポートで単純なケースですが、私はこのタイプのモジュールを定義する自由を取るつもりです.
ELMアプリへのリファレンスを取得する
今我々は我々のタイプを持って、我々は我々のアプリを得ることができます.これは、JavaScriptのELM(v 0.19)ポートを書いている誰にも身近に見えるべきです.The
イベントの配線
これはたくさんのように見えます、しかし、我々がしているすべては
The
HTMLマークアップにまとめます
今、すべてのそれを残して私たちのHTMLマークアップで一緒にすべてを置くことです.
それは我々のプロジェクトを終了!再び、完成した例を見つけることができますon my demo site , and full source here . あなたが質問をするならば私に知らせてください!
最近、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
]
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
SendString str -> { model | str = str }
|> \m -> ( m, Ports.toReScript m.str )
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 */
@bs.val @bs.scope("document")
external getElementById: string => Dom.element = "getElementById"
@bs.get external getValue: Dom.element => string = "value"
@bs.set external setValue: (Dom.element, string) => unit = "value"
@bs.set
external setOnInput: (Dom.element, Dom.event => unit) => unit = "oninput"
@bs.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: getElementById("elm-target") });
結果は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ポートを書く), 我々は、より多くの情報をここで見つけました https://dev.to/webbureaucrat/writing-elm-ports-in-rescript-4e19テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol