Упрощение кнопки, которая при нажатии изменяет логическое значение

Я создал кнопку, которая содержит логическое значение, и когда вы нажимаете на нее, она меняет это значение и текст внутри кнопки. Приведенный ниже код работает, но у меня такое чувство, что я делаю перебор. Как я могу написать эту кнопку настолько просто, насколько это возможно, но в соответствии с архитектурой ELM?

module BtnPin where

import Html exposing ( Html )
import Html.Events as E
import StartApp.Simple as StartApp

-- MAIN

main =
  StartApp.start { model = emptyModel, view = view, update = update }

-- MODEL

type alias Model =
    {pinned : Bool}

init : Model
init = Model False

emptyModel : Model
emptyModel =
    { pinned = False
    }

pin : Model -> Model
pin model =
    if model.pinned then
        Model False
    else
        Model True

viewPin : Signal.Address Action -> Model -> Html
viewPin address model =
    if model.pinned == True then
        Html.button
            [ E.onClick address Pin ]
            [ Html.text <| "Unpin" ]
    else
        Html.button
            [ E.onClick address Pin ]
            [ Html.text <| "Pin" ]

-- UPDATE

type Action = Pin 

update : Action -> Model -> Model
update action model =
  pin model 

-- VIEW

view : Signal.Address Action -> Model -> Html
view address model =
    Html.div []
    [ viewPin address model ]

elm
person Stanko    schedule 05.12.2015    source источник


Ответы (1)


Чем более ясен ваш текст и чем ближе вы остаетесь к архитектуре Elm, тем легче его будет прочитать тому, кто знает шаблон. Его также легко расширить. Но, конечно, вы можете упростить компонент, который вы не ожидаете изменить.

Просто помните, что с кодом, который у вас есть в вашем вопросе, единственная документация, которая вам нужна, — это описание из одного предложения, потому что код — это архитектура Elm, все имеет аннотации типов и очень просто. Когда вы сжимаете свой код, вам может понадобиться дополнительная документация.

Упрощенная кнопка:

module BtnPin where

import Html exposing ( Html )
import Html.Events as E
import StartApp.Simple as StartApp

main =
  StartApp.start { model = False, view = view, update = always not }

-- VIEW

view : Signal.Address () -> Bool -> Html
view address model =
  Html.div [] [ viewPin address model ]

viewPin : Signal.Address () -> Bool -> Html
viewPin address model =
  let
    text = if model then "Unpin" else "Pin"
  in
    Html.button
      [ E.onClick address () ]
      [ Html.text text ]

Это может быть немного экстремально, поэтому вы можете пойти на компромисс, определив функцию update, тип Model и тип Action. Но тогда вы довольно близки к тому, с чего начали...

person Apanatshka    schedule 05.12.2015
comment
Спасибо, я запутался в адресах даже в собственном коде. Знаете ли вы какую-нибудь хорошую документацию о том, как работать с адресами? Например, какой адрес появляется в view address model при запуске программы? - person Stanko; 05.12.2015
comment
Взгляните на исходный код StartApp.Simple. Там всего несколько строк кода. Короче говоря, StartApp создает Signal.mailbox и Signal.foldp поверх mailbox.signal. Адрес этого почтового ящика отправляется в представление. - person pdamoc; 07.12.2015