Desenvolvimento

21 set, 2016

Como construir sua primeira aplicação com Elm – Parte 02

Publicidade

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!