This page covers Elm 0.18


The following pages explain a composition pattern in Elm where you split your messages, models and views in logical groups.

It looks like:

  - Model
  - Messages
  - Update
  - Views

    - Model
    - Messages
    - Update
    - Views

Group in this case could be a resource (e.g. users), a UI element (e.g. a dropdown), a sub application.

Use with care

In general it is recommended that you keep your models and messages shallow. This allows to have less boilerplate when working with Elm. Don't think in term of "components" in Elm. It is better to think about views on one side and messages and models on another, not necessarily coupled.

Composition with the Elm Architecture

Sometimes we still want to compose like this. To understand how this works, let's build an example:

  • We will have a parent component App
  • And a child component Widget

Child component

Let's begin with the child component. This is the code for Widget.elm.

module Widget exposing (..)

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


type alias Model =
    { count : Int

initialModel : Model
initialModel =
    { count = 0


type Msg
    = Increase


view : Model -> Html Msg
view model =
    div []
        [ div [] [ text (toString model.count) ]
        , button [ onClick Increase ] [ text "Click" ]


update : Msg -> Model -> ( Model, Cmd Msg )
update message model =
    case message of
        Increase ->
            ( { model | count = model.count + 1 }, Cmd.none )

This component is nearly identical to the application that we made in the last section, except for subscriptions and main. This component:

  • Defines its own messages (Msg)
  • Defines its own model
  • Provides an update function that responds to its own messages, e.g. Increase.

Note how the component only knows about things declared here. Both view and update only use types declared within the component (Msg and Model).

In the next section we will create the parent component.

results matching ""

    No results matching ""