ReasonML에서 Elm 포트를 작성하는 방법

최근에 나는 bs-elm-es6 라는 npm 패키지를 발표하고 몇 가지 프로젝트에 생산에 들어갔다.그것의 자술문서는 그에 대해 간단명료하게 기록되었지만, 나는 그것이 완전한 문장이 될 만하다고 생각한다.이 문서에서는 BuckleScript 7을 사용하여 elm 0.19 프로젝트의 포트를 드나드는 방법을 설명합니다.(궁금하시면 새 npm 패키지를 얻을 때까지 재명명명/새 문법에 대한 결정을 미루겠습니다.)

대상: 포트를 통해 ReasonML과 Elm 간 공유 제어


최종 제품의 목적은 중복성을 최대한 줄이고 이해하기 쉬워 반드시 쓸모가 있는 것은 아니다.이런 상황에서 이 아주 작은 라이브러리의 기능을 보여주는 가장 좋은 페이지는 아주 작은 웹 응용 프로그램이라고 생각합니다. 두 개의 텍스트 상자가 있는 응용 프로그램으로 실시간 통신을 보여주는 ReasonML 응용 프로그램과 Elm 응용 프로그램입니다.너는 이런 응용 프로그램here을 찾을 수 있다.
이 두 텍스트 상자를 가지고 노는 데 시간이 좀 걸립니다.첫 번째 사용자는 Reasonland에 살지만, 입력 이벤트에서 Reason은 그 내용을 Elm 프로그램에 보냅니다.두 번째는 Elmland에 존재하지만, 입력 이벤트에서 다른 포트를 통해 입력을 Reason 스크립트에 보냅니다.결과는 항상 일치하는 두 개의 텍스트 상자입니다.
일반적인 상황에서, 나는 elm 응용 프로그램 이외의 텍스트 상자를 영원히 가지고 있지 않을 것이다. 나는 전체 보기의 제어권을 elm에게 맡기지만, 이 응용 프로그램은 인덱스 DB 저장소나 myChicago area COVID-19 tracker의 경우, 일부 JSON 데이터에 대한 HTTP 호출이 있을 것이라고 생각하기 쉽다.

기본 elm 설정


기본적인 elm 프로젝트를 어떻게 작성하는지에 대한 상세한 설명은 이런 게시물의 범위를 넘어섰지만, 완전하게 보기 위해서, 나는 여기에 일부 elm 코드가 있기를 바란다. 이렇게 하면 나는 이런 프로젝트를 완전히 복제할 수 있고, 프레젠테이션 프로젝트의 원본 코드를 되돌릴 필요가 없다.
두 가지 기본 메시지 SendStringUpdateString 를 시작하겠습니다. 이것은 정보 유입과 유출 응용 프로그램의 두 방향을 대표합니다.
조미료느릅나무
module Msg exposing (..)

type Msg = SendString String | UpdateString String
Elm 포트에 익숙하다면, Elm 포트의 JSON 인코딩/디코딩에 익숙해야 합니다.이것은 내가 보여 주려고 하는 범위를 넘어섰기 때문에, 이 문자열은 가능하지만, 안전하게 JSON을 해석하는 것은 최선의 실천이며, 대상 유형에 대해 당신이 그것을 이해해야 합니다.이를 위해서는 문자열만으로도 충분하다.
나는 또한 이 elm 응용 프로그램에 두 개의 포트가 있어서 이 elm 응용 프로그램에 들어가는 양방향 데이터 흐름을 다시 표시하기를 바란다.
항구.느릅나무
port module Ports exposing (..)

port toReason : 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.toReason 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에 연결됩니다.

ReasonML 프로젝트 설정


그런 다음 새 BuckleScript 프로젝트를 초기화하고 설치bs-elm-es6를 계속하여 bs-dependencies에 추가합니다.
마지막으로 Index.re 파일을 열고 모듈을 공개합니다.
open ElmES6;

온전함을 위하여


다음에 나는 포트를 둘러싼 논리를 정의할 것이다.나는 이 함수로 나의 포트를 구성할 것이다.
이 코드를 상세하게 해석하는 것은 본문의 범위를 넘어섰다.기본적으로 내가 하는 일은 내가 필요로 하는 기본DOM 기능의 귀속을 정의하는 것이다. 예를 들어 입력한 값을 설정하고 aJavaScripttarget에서 얻는 것이다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 inputReason: Dom.element = getElementById("input-reason");

포트를 레코드의 필드로 선언


elm 프로그램을 초기화하려면 기록 형식의 형식 매개 변수가 필요합니다. 이 매개 필드는 elm 프로그램의 포트를 대표합니다.ElmES6 패키지는 두 가지 유형Elm.sendable('t)Elm.subscribable('t)을 포함하기 때문에 우리는 정보를 우리 elm 응용 프로그램에 보내고 구독할 수 있다.
이 프로그램은 단지 두 개의 포트만 있는 간단한 예일 뿐이지만, 이러한 유형에 대해 모듈을 정의할 것입니다. 그러면 나중에 필요하면 새 파일로 이동할 수 있습니다.
module Ports = 
{
  type t = 
  { 
    toElm: Elm.sendable(string), 
    toReason: Elm.subscribable(string) 
  };
};

elm 프로그램의 인용 가져오기


기왕 우리가 자신의 유형을 가지게 된 이상 우리는 우리의 응용 프로그램을 얻을 수 있다.이것은 자바스크립트로 elm(v0.19) 포트를 작성하는 모든 사람들에게 익숙해야 한다.init 함수에서 기록을 얻었습니다. 이 기록에는 node 형식의 필드가 있습니다Dom.element.
/* get app */
let app: Elm.app(Ports.t) = 
  Elm.Main.init({ node: getElementById("elm-target") });
결과적으로 Elm.app는 우리가 포트에 접근할 수 있도록 하기 때문에 그것을 사용하도록 한다.

사건을 연계하다


이것은 보기에 매우 많지만, 우리가 하는 일은 Dom.element inputReason 라고 명명하고, oninput 이벤트를 Dom.event 함수로 설정하는 것뿐이다.
우리가 이전에 얻은 app에는 ports라는 구성원이 한 명(elm에서 자바스크립트 포트에 있는 것처럼)이고, ElmES6가방은 send이 귀속되어 있기 때문에 우리sendevent.target.value는 자바스크립트에 있는 것과 같다.
inputReason 
  -> setOnInput(event => app.ports.toElm 
                           -> Elm.send(event 
                                         -> getTarget 
                                         -> getValue));
다음은 더 이해하기 쉽다.여기에서, 우리 elm 프로그램이 포트를 통해 값을 보낼 때마다, 나는 subscribe 귀속을 사용하여 inputReason 값을 설정한다.
app.ports.toReason 
  -> Elm.subscribe(str => setValue(inputReason, str));
인덱스를 얻기 위해 컴파일합니다.bs.js.

HTML 태그에 배치하기


이제 남은 것은 그것들을 우리의 HTML 태그에 넣는 것이다.
  <div class="div-reason-demo">
    <h2 class="h2">Controlled by ReasonML</h2> 
    <input class="input" id="input-reason" 
           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/reason/src/Index.bs.js" type="module"></script>
이것은 응용 프로그램이 원하는 모든 것을 제공합니다. 1) '입력 원인' 텍스트 상자, 2) 'elm 목표' div, 그리고 3) 스크립트에 대한 인용입니다.
이것으로 우리의 프로젝트를 완성했다!마찬가지로 완전한 예시herefull source here를 찾을 수 있다.
만약 당신에게 어떤 문제가 있으면 나에게 말해 주세요.

좋은 웹페이지 즐겨찾기