|
| 1 | +# About |
| 2 | + |
| 3 | +Probably the most famous and widely copied part of Elm is The Elm Architecture, which is a simple pattern for architecting web applications, and is how all Elm web applications are written. |
| 4 | + |
| 5 | +The core idea is that your code is built around a `Model` of your application state, a way to `update` your model, and a way to `view` your model. |
| 6 | + |
| 7 | +The `Model` contains the application’s state - all the data that the application needs. |
| 8 | +It can be any type, but in any useful application it is always a [record][record]. |
| 9 | +If you imagine a simple application with a text box, and text showing the reverse of that text, the model would look like below.You can also see this example on the [Elm Guide][elm-guide-text-fields] |
| 10 | + |
| 11 | +```elm |
| 12 | +type alias Model = |
| 13 | + { text : String |
| 14 | + } |
| 15 | +``` |
| 16 | + |
| 17 | +`update` is a function that gets called with a `Msg` when there's a change (like the user clicking a button). |
| 18 | +It takes the current `Model` and the `Msg`, and returns a new `Model`. |
| 19 | + |
| 20 | +```elm |
| 21 | +type Msg |
| 22 | + = TextChanged String |
| 23 | + |
| 24 | +update : Msg -> Model -> Model |
| 25 | +update msg model = |
| 26 | + case msg of |
| 27 | + TextChanged newText -> |
| 28 | + { model | text = newText } |
| 29 | +``` |
| 30 | + |
| 31 | +`view` is a function that returns html to show to the user in the browser. It takes the current `Model` and returns an `Html Msg` (the type that Elm uses to represent Html). |
| 32 | +It can specify that certain events, like clicking a button or editing text in a text box, result in a `Msg` being created, which the Elm Runtime will use to call the update function and generate updated Html. |
| 33 | +In the code below this happens with `onInput TextChanged`. |
| 34 | +`onInput` expects to be passed a function (`String -> Msg`) which it will use to create the `Msg`. Different events expect different functions depending on what information they can provide, so for example `onCheck` (for checkboxes) expects `Bool -> Msg` and `onClick` just expects a `Msg`. |
| 35 | +The Elm language is pure and functional and no mutation is possible, so the Elm runtime handles all the things that change. |
| 36 | +You can see all of the different [Html Elements][html-elements], [Element Attributes][element-attributes] and [Html Events][html-events] on the Elm package registry. |
| 37 | + |
| 38 | +```elm |
| 39 | +view : Model -> Html Msg |
| 40 | +view model = |
| 41 | + div [] |
| 42 | + [ input [ placeholder "Text to reverse", value model.text, onInput TextChanged ] [] |
| 43 | + , div [] [ text (String.reverse model.text) ] |
| 44 | + ] |
| 45 | +``` |
| 46 | + |
| 47 | +There are 4 "levels" of web application you can write in Elm, that get progressively more powerful and more complicated (although Elm remains a delightfully simple language and ecosystem). |
| 48 | +These are all defined in the [Browser package][browser-package] |
| 49 | + |
| 50 | +- [sandbox][browser-sandbox] — react to user input, like buttons and checkboxes |
| 51 | +- [element][browser-element] — talk to the outside world, like HTTP and JS interop |
| 52 | +- [document][browser-document] — control the `<title>` and `<body>` of a web page |
| 53 | +- [application][browser-application] — create full single-page appliations that handle routing / url changes |
| 54 | + |
| 55 | +This concept uses the [sandbox][browser-sandbox], as it is the simplest (and because it is a sandbox, it is relatively easy to work with the Exercism online editor). |
| 56 | +By convention the entry module for an Elm program must be called `Main`, and the function that creates the application must be called `main`, as below. |
| 57 | +We have already seen the `update` and `view` functions, and the [sandbox][browser-sandbox] additionally requires an `init` function, to return the initial state of the `Model`. |
| 58 | + |
| 59 | +```elm |
| 60 | +import Browser |
| 61 | +import Html exposing (Html, Attribute, div, input, text) |
| 62 | +import Html.Attributes exposing (..) |
| 63 | +import Html.Events exposing (onInput) |
| 64 | + |
| 65 | +main = |
| 66 | + Browser.sandbox { init = init, update = update, view = view } |
| 67 | + |
| 68 | +init : Model |
| 69 | +init = |
| 70 | + { text = "" } |
| 71 | + |
| 72 | +-- Add Model, Msg, update and view here |
| 73 | +``` |
| 74 | + |
| 75 | +[record]: https://elm-lang.org/docs/records |
| 76 | +[elm-guide-text-fields]: https://guide.elm-lang.org/architecture/text_fields |
| 77 | +[html-elements]: https://package.elm-lang.org/packages/elm/html/latest/Html |
| 78 | +[element-attributes]: https://package.elm-lang.org/packages/elm/html/latest/Html-Attributes |
| 79 | +[html-events]: https://package.elm-lang.org/packages/elm/html/latest/Html-Events |
| 80 | +[browser-package]: https://package.elm-lang.org/packages/elm/browser/latest/ |
| 81 | +[browser-sandbox]: https://package.elm-lang.org/packages/elm/browser/latest/Browser#sandbox |
| 82 | +[browser-element]: https://package.elm-lang.org/packages/elm/browser/latest/Browser#element |
| 83 | +[browser-document]: https://package.elm-lang.org/packages/elm/browser/latest/Browser#document |
| 84 | +[browser-application]: https://package.elm-lang.org/packages/elm/browser/latest/Browser#application |
0 commit comments