수색…


소개

응용 프로그램을 구성하는 데 권장되는 방법은 '느릅 나무 건축술 (Elm Architecture)'입니다.

간단한 프로그램은 구성 model 업데이트 할 수있는 모든 데이터를 저장하는 기록 노동 조합 유형 Msg 프로그램이 데이터, 기능 업데이트 방법을 정의 update 모델과 소요 Msg 새로운 모델을 리턴을하고, 기능 view 있는 모델을 사용하고 페이지에 표시 할 HTML을 반환합니다. 함수가 Msg 반환 할 때마다 Elm 런타임은이를 사용하여 페이지를 업데이트합니다.

초급 프로그램

HTML 은 주로 학습 목적으로 beginnerProgram 가지고 beginnerProgram .

beginnerProgram 은 구독을 처리하거나 명령을 실행할 수 없습니다.

DOM 이벤트로부터의 사용자 입력 만 처리 할 수 ​​있습니다.

model 을 렌더링하는 view 와 상태 변경을 처리하는 update 함수 만 있으면됩니다.

beginnerProgram 최소한의 예제를 고려하십시오.

이 예제의 model 은 단일 Int 값으로 구성됩니다.

update 함수에는 model 저장된 Int 를 증가시키는 하나의 분기 만 model .

view 는 모델을 렌더링하고 클릭 DOM 이벤트를 첨부합니다.

초기화 및 빌드 에서 예제를 빌드하는 방법을 참조하십시오.

import Html exposing (Html, button, text)
import Html exposing (beginnerProgram)
import Html.Events exposing (onClick)


main : Program Never
main =
    beginnerProgram { model = 0, view = view, update = update }


-- UPDATE


type Msg
    = Increment

update : Msg -> Int -> Int
update msg model =
    case msg of
        Increment ->
            model + 1


-- VIEW


view : Int -> Html Msg
view model =
    button [ onClick Increment ] [ text ("Increment: " ++ (toString model)) ]

프로그램

program 은 초기화에 외부 데이터가 필요없는 응용 프로그램에 적합합니다.

구독 및 명령을 처리 할 수 ​​있으므로 JavaScript 또는 HTTP 통신과 같은 I / O를 처리 할 수있는 기회가 더 많아집니다.

초기 상태는 모델과 함께 시작 명령을 반환하는 데 필요합니다.

program 을 초기화하려면 model , viewupdate 와 함께 subscriptions 을 제공해야합니다.

타입 정의를 보라 :

program :
    { init : ( model, Cmd msg )
    , update : msg -> model -> ( model, Cmd msg )
    , subscriptions : model -> Sub msg
    , view : model -> Html msg
    }
    -> Program Never

설명 할 수있는 가장 간단한 방법, 구독 을 사용하는 방법은 JavaScript를 사용하여 간단한 포트 통신을 설정하는 것입니다.

초기화 및 빌드 / HTML로 삽입 하기에서 예제를 빌드하는 방법을 참조하십시오.

port module Main exposing (..)

import Html exposing (Html, text)
import Html exposing (program)


main : Program Never
main =
    program
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }


port input : (Int -> msg) -> Sub msg


-- MODEL


type alias Model =
    Int


init : ( Model, Cmd msg )
init =
    ( 0, Cmd.none )


-- UPDATE


type Msg = Incoming Int


update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
    case msg of
        Incoming x ->
          ( x, Cmd.none )


-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
    input Incoming


-- VIEW


view : Model -> Html msg
view model =
    text (toString model)
<!DOCTYPE html>
<html>
    <head>
        <script src='elm.js'></script>
</head>
    <body>
    <div id='app'></div>
    <script>var app = Elm.Main.embed(document.getElementById('app'));</script>
    <button onclick='app.ports.input.send(1);'>send</button>
</body>
</html>

플래그 프로그램

programWithFlags 에는 program 과 단 하나의 차이점 만 program .

자바 스크립트에서 초기화시 데이터를 받아 들일 수 있습니다 :

var root = document.body;
var user = { id: 1, name: "Bob" };
var app = Elm.Main.embed( root, user );

JavaScript에서 전달 된 데이터를 Flags라고합니다.

이 예에서는 사용자 정보가있는 JavaScript 객체를 Elm에 전달하고 있으므로 플래그에 유형 별칭을 지정하는 것이 좋습니다.

type alias Flags =
    { id: Int
    , name: String
    }

플래그는 init 함수에 전달되어 초기 상태를 생성합니다.

init : Flags -> ( Model, Cmd Msg )
init flags =
    let
        { id, name } =
            flags
    in
        ( Model id name, Cmd.none )

형식 시그니처와 다른 점을 알 수 있습니다.

programWithFlags :
    { init : flags -> ( model, Cmd msg )          -- init now accepts flags
    , update : msg -> model -> ( model, Cmd msg )
    , subscriptions : model -> Sub msg
    , view : model -> Html msg
    }
    -> Program flags

초기화 코드는 거의 같지만 init 함수 만 다르기 때문에 비슷합니다.

main =
    programWithFlags
        { init = init
        , update = update
        , view = view
        , subscriptions = subscriptions
        }

한 가지 방법으로 부모 - 자식 커뮤니케이션

예제에서는 구성 요소 구성과 부모에서 자식으로의 단방향 메시지 전달을 보여줍니다.

0.18.0

구성 요소 구성은 Html.App.map 사용하여 메시지 태그 지정을 사용 Html.App.map

0.18.0

0.18.0 HTML.App HTML 로 축소되었습니다.

구성 요소 구성은 Html.mapHtml.map 메시지 태그 지정에 의존합니다.

초기화 및 빌드 에서 예제를 빌드하는 방법을 참조하십시오.

module Main exposing (..)

import Html exposing (text, div, button, Html)
import Html.Events exposing (onClick)
import Html.App exposing (beginnerProgram)


main =
    beginnerProgram
        { view = view
        , model = init
        , update = update
        }

{- In v0.18.0 HTML.App was collapsed into HTML
   Use Html.map instead of Html.App.map
-}
view : Model -> Html Msg
view model =
    div []
        [ Html.App.map FirstCounterMsg (counterView model.firstCounter)
        , Html.App.map SecondCounterMsg (counterView model.secondCounter)
        , button [ onClick ResetAll ] [ text "Reset counters" ]
        ]


type alias Model =
    { firstCounter : CounterModel
    , secondCounter : CounterModel
    }


init : Model
init =
    { firstCounter = 0
    , secondCounter = 0
    }


type Msg
    = FirstCounterMsg CounterMsg
    | SecondCounterMsg CounterMsg
    | ResetAll


update : Msg -> Model -> Model
update msg model =
    case msg of
        FirstCounterMsg childMsg ->
            { model | firstCounter = counterUpdate childMsg model.firstCounter }

        SecondCounterMsg childMsg ->
            { model | secondCounter = counterUpdate childMsg model.secondCounter }

        ResetAll ->
            { model
                | firstCounter = counterUpdate Reset model.firstCounter
                , secondCounter = counterUpdate Reset model.secondCounter
            }


type alias CounterModel =
    Int


counterView : CounterModel -> Html CounterMsg
counterView model =
    div []
        [ button [ onClick Decrement ] [ text "-" ]
        , text (toString model)
        , button [ onClick Increment ] [ text "+" ]
        ]


type CounterMsg
    = Increment
    | Decrement
    | Reset


counterUpdate : CounterMsg -> CounterModel -> CounterModel
counterUpdate msg model =
    case msg of
        Increment ->
            model + 1

        Decrement ->
            model - 1

        Reset ->
            0

Html.App.map로 메시지 태그 지정

구성 요소는 자신의 메시지를 정의하고 방출 된 DOM 이벤트 뒤에 전송됩니다 (예 : 부모 - 자식 통신의 CounterMsg

type CounterMsg
    = Increment
    | Decrement
    | Reset

이 구성 요소의 뷰는 CounterMsg 유형의 메시지를 전송하므로 뷰 유형 서명은 Html CounterMsg 입니다.

재사용 할 수 있으려면 counterView 부모 구성 요소의 내부보기를, 우리는 모든 통과해야 CounterMsg 부모를 통해 메시지를 Msg .

이 기술을 메시지 태그 지정 이라고 합니다 .

부모 구성 요소는 하위 메시지 전달을위한 메시지를 정의해야합니다.

type Msg
    = FirstCounterMsg CounterMsg
    | SecondCounterMsg CounterMsg
    | ResetAll

FirstCounterMsg Increment 는 태그가 지정된 메시지입니다.

0.18.0

counterView 에서 태그가 추가 된 메시지를 보내려면 Html.App.map 함수를 사용해야합니다.

Html.map FirstCounterMsg (counterView model.firstCounter)
0.18.0

HTML.App 패키지는 붕괴되었다HTML 에서 패키지 v0.18.0

counterView 에서 태그가있는 메시지를 보내려면 Html.map 함수를 사용해야합니다.

Html.map FirstCounterMsg (counterView model.firstCounter)

이렇게하면 형식 시그니처 Html CounterMsg -> Html Msg 되므로 부모보기 내부에서 카운터를 사용하고 부모 업데이트 기능으로 상태 업데이트를 처리 할 수 ​​있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow