Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
wiki2:elm-programming [2020/05/13 17:20] alfred [Send inner messages] |
wiki2:elm-programming [2021/05/02 10:06] (actual) |
||
|---|---|---|---|
| Línea 50: | Línea 50: | ||
| Messages and commands are not synonymous. Messages represent the communication between an end user and the application while commands represent how an Elm application communicates with other entities. A command is triggered in response to a message. | Messages and commands are not synonymous. Messages represent the communication between an end user and the application while commands represent how an Elm application communicates with other entities. A command is triggered in response to a message. | ||
| - | ==== Commands ==== | ||
| - | |||
| - | |||
| + | The type ''Message'' is defined my the user, sometimes called ''Msg''. Again, it's upon the user. | ||
| ==== To trigger several commands ==== | ==== To trigger several commands ==== | ||
| <code> | <code> | ||
| Línea 69: | Línea 67: | ||
| + | ==== Trigger after one calling ==== | ||
| + | |||
| + | You can do something like this for sending message ''UpdateTotals'' with value 100: | ||
| + | <code> | ||
| + | GetAccount result -> case result of | ||
| + | Ok account -> ({model | account = account }, Task.succeed (UpdateTotals 100.0) |> Task.perform identity) | ||
| + | Err err -> log (toString err) (model, Cmd.none) | ||
| + | </code> | ||
| + | |||
| + | Or just define: | ||
| + | <code> | ||
| + | send : msg -> Cmd msg | ||
| + | send msg = Task.succeed msg |> Task.perform identity | ||
| + | </code> | ||
| + | |||
| + | ==== Notes ==== | ||
| + | * If something waits for a Command but you do not have any Command to apply you can send ''Cmd.none''. | ||
| ===== Subscriptions ===== | ===== Subscriptions ===== | ||
| Línea 136: | Línea 151: | ||
| ==== Flags. Js values on app initialization ==== | ==== Flags. Js values on app initialization ==== | ||
| - | Flags are a way to pass values into Elm on initialization. | + | Flags are a way to pass values into Elm on initialization. The idea is that you use the type of those values that are passed to your script for produce the first model status. |
| + | |||
| + | So an initial function like this: | ||
| + | <code> | ||
| + | init : () -> (Model, Cmd Msg) | ||
| + | init _ = | ||
| + | ( initialModel, Http.get{ url = "/api/bookmarks", expect = Http.expectJson BookmarksReceived resultsDecoder} ) | ||
| + | </code> | ||
| + | |||
| + | With Flags will be similar to this: | ||
| + | <code> | ||
| + | init : FlagsType -> (Model, Cmd Msg) | ||
| + | </code> | ||
| In JS we can create the application with the chosen flags: | In JS we can create the application with the chosen flags: | ||
| Línea 196: | Línea 223: | ||
| * Ports are available for applications, not for packages. | * Ports are available for applications, not for packages. | ||
| - | === JS -> Elm === | + | === Ports: JS -> Elm === |
| In javascript: | In javascript: | ||
| <code javascript> | <code javascript> | ||
| Línea 224: | Línea 251: | ||
| - | === Elm -> JS === | + | === Ports: Elm -> JS === |
| In Elm: | In Elm: | ||
| Línea 315: | Línea 342: | ||
| ===== Encoders and Decoders ===== | ===== Encoders and Decoders ===== | ||
| - | :!: | + | ==== Useful ==== |
| + | === succeed === | ||
| + | |||
| + | You can set a fixed value with ''Decode.succeed'': | ||
| + | <code> | ||
| + | decodePageGroupForm : T.PageGroup -> D.Decoder T.PageGroup | ||
| + | decodePageGroupForm group = D.map5 T.PageGroup | ||
| + | (D.succeed group.uuid) | ||
| + | (D.at ["target", "title", "value"] D.string) | ||
| + | (D.succeed group.subtitle) | ||
| + | (D.succeed group.order) | ||
| + | (D.succeed group.pages) | ||
| + | | ||
| + | |||
| + | zineDecoder : D.Decoder T.Zine | ||
| + | zineDecoder = D.map4 T.Zine | ||
| + | (D.field "uuid" D.string) | ||
| + | (D.field "title" D.string) | ||
| + | (D.field "cover" D.string) | ||
| + | {- (D.maybe (D.field "groups" <| D.list groupDecoder)) -} | ||
| + | (D.maybe (D.succeed [])) | ||
| + | </code> | ||
| + | |||
| + | === oneOf === | ||
| + | |||
| + | It tries a decoder, if fails, tries the next one and so on: | ||
| + | <code> | ||
| + | groupDecoder : D.Decoder T.PageGroup | ||
| + | groupDecoder = D.map5 T.PageGroup | ||
| + | (D.field "uuid" D.string) | ||
| + | (D.field "title" D.string) | ||
| + | (D.oneOf [D.field "subtitle" D.string, D.succeed ""]) -- If subtitle is null, a different type than string... it will put "" | ||
| + | (D.field "order" D.int) | ||
| + | (D.field "pages" <| D.list pageDecoder) | ||
| + | </code> | ||
| + | |||
| + | ==== Maps ==== | ||
| + | |||
| + | Lets imagine we want to produce a ''Message'' when the Decoder has decoded the the object. | ||
| + | |||
| + | |||
| + | This can be chained. Lets imagine the [[https://package.elm-lang.org/packages/elm/html/latest/Html-Events#preventDefaultOn|preventDefaultOn]] of a form: | ||
| + | <code> | ||
| + | type Message = FormSubmission FormFields | ||
| + | |||
| + | type alias FormFields = { ... } | ||
| + | |||
| + | update : Message -> Model -> Model | ||
| + | update msg model = case msg of | ||
| + | FormSubmission _ -> { model | counter = model.counter + 1 } | ||
| + | |||
| + | decodeForm = Decode.map2 FormFields ... | ||
| + | |||
| + | view : Model -> Html.Html Message | ||
| + | view model = | ||
| + | let | ||
| + | alwaysPreventDefault : msg -> ( msg, Bool ) | ||
| + | alwaysPreventDefault msg = ( msg, True ) | ||
| + | in | ||
| + | Html.div [] [ | ||
| + | Html.form [Events.preventDefaultOn "submit" (Decode.map alwaysPreventDefault (Decode.map FormSubmission decodeForm))] [ | ||
| + | ... | ||
| + | </code> | ||
| ===== Useful types ===== | ===== Useful types ===== | ||
| Línea 366: | Línea 455: | ||
| ==== Create a program without a view ==== | ==== Create a program without a view ==== | ||
| Use ''Platform.worker''. Documentation [[https://package.elm-lang.org/packages/elm/core/1.0.5/Platform#worker|here]]. | Use ''Platform.worker''. Documentation [[https://package.elm-lang.org/packages/elm/core/1.0.5/Platform#worker|here]]. | ||
| - | ===== Gotchas ===== | ||
| - | Every function that accepts two arguments can be converted in one that accepts one argument: | ||
| - | <code> | ||
| - | > String.repeat | ||
| - | <function> : Int -> String -> String | ||
| - | |||
| - | > String.repeat 4 | ||
| - | <function> : String -> String | ||
| - | </code> | ||