A component is a independent part in the system and has a single responsibility. They can not import other components.
Components are like normal elm programs. They have their own model, they can do commands and subscriptions. In addition to that they also have out messages.
This means you will have two Msg types: MsgIn and MsgOut. MsgIn
is conceptually the same as your normal Msg type would be.
MsgOut is a way to "tell" the rest of the system that something happened in your component.
For Example, the msg types for a login form component could look like this:
type MsgIn
= EmailFieldChanged String
| PasswordFieldChanged String
| SubmitbuttonClicked
type MsgOut
= FormWasSubmitted
{ email : String
, password : String
}From the system's perspective, this is all you need to care about. This is the public API for the component.
The normal output tuple from the init and update functions are replaced with
a 3-Tuple:
( Model, List MsgOut, Cmd MsgIn )A UI-component is very similar in concept to a Browser.element program.
UI Component Type
The service component does not have any view function. Remember Platform.worker?
Service Component Type
A layout component can render other components using their PID as a reference. The difference comparing to a UI component is the view function.
Layout Component Type
The view function of a layout component:
view : (MsgIn -> msg) -> Model -> (PID -> Html msg) -> Html msg
view toSelf model renderPID =
div
[]
[ renderPID model.child
, button [ onClick (toSelf ButtonWasClicked) ] [ text "Button!" ]
]The view function has three arguments:
toSelf is used to wrap all event-handlers from Html.EventsrenderPID is used to render other components.As you can see, the output type of the view function is Html msg. This is
necessary to allow components to be composed. What would the return type be on
renderPID if they were not mapped to the same type?
There is no native elm module for a Tuple with three arguments.
Map the first argument (Model).
Map the second argument (List MsgOut).
Map the third argument (Cmd).
Run a series of updates on the model
The msgOut's and Cmd's will be composed using System.batch and
Cmd.batch.
( model, [], Cmd.none )
|> Component.andThen doSomethingWithModelAdd an out message to the output 3-Tuple.
( model, [], Cmd.none )
|> Component.addOutMsg SomeOutMsgAdd a Cmd to the output 3-Tuple.
( model, [], Cmd.none )
|> Component.addCmd cmdConvert a msg to Cmd.
Convert a msg to Cmd with a timeout in milliseconds.
Sometimes you'd want to put messages in a queue. Maybe your component is in a state where it can't process them at this point, eg. an InitState.
Store messages in a queue.
Create an Empty Queue
{ model
| queue = Component.emptyQueue
}Add a msg to the queue
{ model
| queue = Component.addToQueue msgIn model.queue
}
A PID is an identifier for a Process.