如何在一个函数中进行两个独立的操作?

时间:2015-06-21 13:17:33

标签: elm

如何在Elm的一个函数中进行两个独立的操作?是否有任何模式或显式功能?

一般来说,我不确定如何在Elm Architecture内实现ajax数据加载。

例如,我想制作Http.get并返回修改后的参数函数,如此

fetchCustomers model =
  Http.get parseCustomers "/customers" `andThen` setCustomers
  { model | fetchingCustomers <- True }

1 个答案:

答案 0 :(得分:3)

TL; DR

你可以通过在元组中返回两者来实现。然后在foldp中拆分更新信号,将模型部分放入视图函数中,并将任务放入端口执行。最后在最后一个模式下的架构帖子中提到了这一点。

更长的答案

由于您链接到Elm Architecture,我也可以链接到它,但特别是最后一部分:One Last Pattern

您要在此处执行的操作是程序“更新”的一部分,您不仅可以更新模型,还可以执行其他操作。因此,您不仅要返回新模型,还要返回您想要做的额外事情(在这种情况下是Http请求):

fetchCustomers model =
  ( { model | fetchingCustomers <- True }
  , Http.get parseCustomers "/customers" `andThen` setCustomers
  )

您可以从包中粘贴start function,而不是像体系结构页一样使用StartApp。现在,您可以访问操作所在的邮箱,因此您可以将其传递给更新,以便在此处发送Http结果。并且您可以将从更新函数返回的元组拆分为实际执行任务:

start app =
  let
    actions =
      Signal.mailbox Nothing

    address =
      Signal.forwardTo actions.address Just

    model =
      Signal.foldp
        (\(Just action) (model,_) -> app.update actions action model)
        -- ignore task: ^     ^^^              ^^^^^^^^:add mailbox
        app.model
        actions.signal
  in
    (Signal.map (fst >> app.view address) model, Signal.map snd model)
--  ^           ^^^^^^^     :split model:      ^^^^^^^^^^^^^^^^^^^^^^^


fetchCustomers actions model =
  ( { model | fetchingCustomers <- True }
  , Http.get parseCustomers "/customers"
    `andThen` (SetCustomers >> Signal.send actions.address)
  -- use mailbox to send Http results as an input action again
  )

-- larger update function you probably have
update actions action model = case action of
  -- ...
  SetCustomers cust -> setCustomers cust
  -- ...
  -- fetchCustomers actions model

(output, tasks) = start { model: model, view: view, update: update }

-- task execution:
port httpGets = tasks

-- output your view
main = output

您可以在“任务”下的网站上找到更多examplesHttp