Semana passada, comecei uma série sobre como criar sua primeira aplicação com Elm. Se você ainda não viu, clique aqui para ver a primeira parte.
Messages
Geralmente, em cada componente da nossa aplicação, temos algumas ações que o usuário pode realizar. A forma de declararmos essas ações com Elm é com o uso das Messages ou Msgs.
Na nossa aplicação, um usuário poderá realizar apenas duas ações: incrementar ou decrementar o contador.
Então, podemos implementá-los desta forma:
type Msg = Increment | Decrement
Se por algum motivo chegar uma nova demanda (e geralmente elas chegam), é bem fácil explicitarmos essas novas ações. Digamos que os usuários agora vão poder também zerar o contador:
type Msg = Increment | Decrement | Reset
Ou então terão o poder apenas de incrementar o contador:
type Msg = Increment
Mas as Msgs, por si só, não fazem muito. Precisamos fazer uma ligação da view com essas ações do usuário para que elas tenham algum efeito visível na aplicação.
Update
As ações que o usuário realiza alteram diretamente o model da aplicação. E essas mudanças precisam ocorrer dentro de uma função update.
A nossa aplicação deverá lidar apenas com dois casos, como falamos anteriormente: Increment e Decrement.
Podemos implementar a função update desta forma:
update msg model = case msg of Increment -> model + 1 Decrement -> model - 1
Vamos novamente analisar linha por linha. A primeira linha demonstra que a função update receberá dois parâmetros:m sg e model.
1. update msg model = 2. case msg of 3. Increment -> 4. model + 1 5. 6. Decrement -> 7. model - 1
Já na segunda linha começamos com um simples case (semelhante ao switch do JavaScript), que vai verificar os dois possíveis cenários para as ações do usuário (linhas 3 e 6):
1. update msg model = 2. case msg of 3. Increment -> 4. model + 1 5. 6. Decrement -> 7. model - 1
Caso a ação seja de incrementar, o modelo será somado de 1:
1. update msg model = 2. case msg of 3. Increment -> 4. model + 1 5. 6. Decrement -> 7. model - 1
Caso contrário, será subtraído de 1:
1. update msg model = 2. case msg of 3. Increment -> 4. model + 1 5. 6. Decrement -> 7. model - 1
Basta agora adicionarmos uma anotação de tipo, e a função update estará finalizada:
update: Msg -> Model -> Model update msg model = case msg of Increment -> model + 1 Decrement -> model - 1
Nosso código completo, até o momento, está assim:
import Html exposing (..) type alias Model = Int model: Model model = 0 view: Model -> Html Msg view model = div [] [ button [] [ text "-" ] , div [] [ text (toString model) ] , button [] [ text "+" ] ] type Msg = Increment | Decrement update: Msg -> Model -> Model update msg model = case msg of Increment -> model + 1 Decrement -> model - 1
View -> Update
Precisamos agora atualizar a view para fazer a conexão dela com a função update.
Vamos primeiro importar o módulo Html.Events, que contém a função onClick que vamos usar para disparar as ações do usuário.
import Html.Events exposing (onClick)
Ou então para padronizar com o resto da aplicação:
import Html.Events exposing (..)
Precisamos apenas modificar nossa função view, nos botões, para que o click do usuário dispare um Increment ou um Decrement:
view: Model -> Html Msg view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ]
A nossa aplicação, então, ficou assim:
import Html exposing (..) import Html.Events exposing (..) type alias Model = Int model: Model model = 0 view: Model -> Html Msg view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ] type Msg = Increment | Decrement update: Msg -> Model -> Model update msg model = case msg of Increment -> model + 1 Decrement -> model - 1
Conectando todas as partes
Toda aplicação construída com Elm segue um padrão que emerge naturalmente:
- Model
- View
- Update
Esse padrão (ou arquitetura) é chamado de The Elm Architecture. Ele é tão comum que existe uma API específica para facilitar a nossa vida e conectar as três pontas: model, view e update.
Primeiro, precisamos importar o módulo Html.App:
import Html.App exposing (..)
E agora basta incluirmos essa linha, que invoca a função beginnerProgram, que por sua vez conectará toda a aplicação exatamente do jeito que nós esperamos:
main = beginnerProgram { model = model, view = view, update = update }
Com isso, nossa aplicação está completa e funcional. A versão final do nosso contador ficou desta forma:
import Html exposing (..) import Html.Events exposing (..) import Html.App exposing (..) main = beginnerProgram { model = model, view = view, update = update } type alias Model = Int model: Model model = 0 view: Model -> Html Msg view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ] type Msg = Increment | Decrement update: Msg -> Model -> Model update msg model = case msg of Increment -> model + 1 Decrement -> model - 1
E pode ser vista em funcionamento aqui.
É isso! Ficou alguma dúvida? Deixe nos campos abaixo. Até a próxima!