Вяз Архитектура и задачи

ОБНОВЛЕНИЕ: теперь это описано в документация по архитектуре Elm.

--

Я не понимаю, как вы связываете архитектуру Elm и задачи.

-- Action is an enumeration of possible actions
type Action = ..

-- Model is a Model that evolves in time
model : Signal Model

-- View turns a model into Html, potentially sending actions to an address
view : Address Action -> Model -> Html

-- Update turns a model and an action into another model
update : Action -> Model -> Model

-- Main waits for new values of the model to be emitted, and pass then to the view action
main : Signal Html
main =
  Signal.map (view actions.address) model

Я пытаюсь смоделировать это:

  • когда пользователь нажимает на кнопку, выдается "DoSomethingAction"
  • это действие должно запускать задачу, обрабатываемую некоторым портом
  • когда задача выполнена, она должна выдать другое действие ("SomethingDoneAction") с результатом

Это правильный путь?

Какие функции следует изменить (обновление, основное)?

Я понимаю, что это то, что упоминается здесь, но объяснение не слишком ясно, и я не понимаю, что нужно изменить.

Таким образом, любой полный пример/или более подробное объяснение будет приветствоваться.

РЕДАКТИРОВАТЬ :

Более полная версия (которая "вроде бы" работает) доступна здесь: http://share-elm.com/sprout/55bf3c3ce4b06aacf0e8ba17

Кажется, я в нескольких шагах от того, чтобы он заработал, поскольку задача не всегда запускается, когда я нажимаю кнопку (но, надеюсь, я куда-то добираюсь).


elm
person phtrivier    schedule 01.08.2015    source источник
comment
Вы, наконец, нашли правильный способ добиться этого?   -  person jarandaf    schedule 29.09.2015
comment
@jarandaf: evancz описал это в документе по архитектуре Elm, я предлагаю вам взглянуть на это еще раз. Радоваться, веселиться !   -  person phtrivier    schedule 29.09.2015
comment
спасибо! Пропущен бит API эффектов   -  person jarandaf    schedule 29.09.2015


Ответы (3)


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

Если вы действительно хотите выполнять задачи, вы можете сделать следующее:

type Action = NoOp | ButtonClicked | SetText String

type alias Model =
  { tasks : Task Http.Error String
  , text : String
  }

init : Model
init =
  { task = Task.succeed "Fetching..."
  , text = ""
  }

-- We can use, for example, the Http.get task
update : Action -> Model -> Model
update action model =
  case action of
    ButtonClicked ->
      { model | task <-
        Http.getString "http://example.org/some-text.txt"}
    SetText t ->
      { model | text <- t }
    _ -> model

view : Address Action -> Model -> Html
view address model =
  div []
   [ div
      [ class "btn btn-default"
      , onClick address ButtonClicked
      ]
      [ text "Click me!" ]
   , h3 "Here is what was fetched:"
   , p [] [ text model.text ]
   ]

-- now possibly in another file

actions : Signal.Mailbox Action
actions : Signal.mailbox NoOp    

model : Signal Model
model = Signal.foldp init update actions.signal

-- This is what actually performs the Tasks
-- The Elm task example also details how to send
port taskPort : Signal (Task Http.Error String)
port taskPort =
  ((.task) <~ model) `andThen`
    (Signal.send actions.address << SetText)

main : Signal Html
main = view actions.address <~ model

Обратите внимание, что вы можете использовать Signal.dropRepeats, если хотите выполнять задачу только при ее изменении.

person rhaps0dy    schedule 01.08.2015
comment
Что должна делать часть (.task) <~ model? Кроме того, я не понимаю, почему alertTask должен быть родным (в моем случае я просто хочу выполнить вызов Http.get в качестве задачи) и как функция «обновить» вернет модель в этом случае... - person phtrivier; 02.08.2015
comment
model = Signal.foldp init update actions.signal не работает. Вместо этого должно быть model = Signal.foldp update init actions.signal. - person Martinos; 16.08.2015
comment
Вы также можете изменить имя поля записи Model с tasks на task. - person Martinos; 16.08.2015

Способ сделать это состоит в том, чтобы обновить модель, сопоставленную с сигналом response, который получает результаты того, на что вы хотите, чтобы ваша модель реагировала.

Представление отправляет задачи в почтовый ящик запроса/запросов.

Порт будет картой сигнала запроса, который выполняет задачи andThen и отправляет результаты в почтовый ящик response.

Если вы хотите увидеть это в действии, взгляните на этот файл (я выделил соответствующие части)

https://github.com/pdamoc/elmChallenges/blob/master/challenge4.elm#L72-L94

Имейте в виду, что то, что вы видите, немного сложнее, чем то, что вам нужно, потому что оно также реализует механизм для выполнения задач только тогда, когда пользователь перестает печатать.

person pdamoc    schedule 03.08.2015
comment
Я полагаю, что та часть, которая мне не понадобится, это Time? Мне удалось сделать что-то, что вроде бы работает, но в некоторых ситуациях мои задачи все еще не выполняются (поэтому у меня где-то что-то не так...) У меня есть суть, к сожалению, трудно объяснить мою проблему, не показывая столько кода ... share-elm.com/sprout/55bf3c3ce4b06aacf0e8ba17 - person phtrivier; 03.08.2015
comment
Да, Time вещи не нужны. Вот версия файла до реализации задержки: github. com/pdamoc/elmChallenges/blob/ Возможно, это более четкая альтернатива. Здесь сигнал запроса используется для создания задачи, которая ищет пользователя. Эта задача используется для создания новой задачи отправки сообщения с результатами первой задачи, и эта задача выполняется port - person pdamoc; 03.08.2015

На это есть ответ в документе:

https://github.com/evancz/elm-architecture-tutorial#user-content-example-5-random-gif-viewer

person phtrivier    schedule 15.01.2016