假设我正在尝试遵循Elm架构,并在使用User
时将我的工作流程拆分为Invoice
和StartApp
。
用户有发票,但他们必须登录才能访问它们。
模型可能看起来像这样的东西:
type Model
= NotLoggedIn Credentials
| LoggedIn RealName (Maybe Invoices)
type alias State =
{ login : Model
, notification : ......
, ......
type alias Invoices = { invoices: List Invoice, ...... }
用户模块有操作:
type Action
= Login (Result Http.Error String)
| Logout
| Submit
...
并更新功能:
update : Action -> Model -> (Model, Effects Action, Notification)
update action user =
case (action, user) of
(Login res, _) ->
case res of
Ok name ->
(LoggedIn name Nothing, Effects.none, Info "Welcome!")
...
我跳过了身份验证的细节,这一切都很好。有趣的部分是Login
动作。元组将发送到step
中的main
函数:
step : Action -> State -> (State, Effects Action)
step action state =
case action of
UserAction a ->
let (newstate, ef, n) = User.update a state.login
in ({ state | login = newstate, notification = n }, Effects.map UserAction ef)
InvoiceAction a -> ......
因此用户已登录。接下来,我们要在init
模块中调用一些Invoice
操作。
但这应该怎样做呢?如何启动Invoice
保护封装的行动?除了Effects.none
之外我还要退还吗?
答案 0 :(得分:4)
这可能是一个案例,可以通过应用程序数据的不同建模来解决。
我理解它的方式,您需要的操作需要用户和不需要用户的操作。 InvoiceAction告诉我它应该属于UserAction。
所以,你可以
type MainAction = UserAction UAction | NonUserAction NonUAction
type UAction = AuthAction Credentials | InvoiceAction Invoice.Action
用户模型将封装登录详细信息和发票详细信息。然后,在成功登录后,您可以重定向到InvoiceAction。
update action model =
case action of
AuthAction credentials ->
let
(isLoggedIn, notifications) = Authentication.check credentials
model' = { model | credentials = credentials, notifications = notifications}
in
if isLoggedIn
then update (Invoice.initialize model'.credentials) model'
else (model', Effects.none)
InvoiceAction act ->
let
(invoices, fx) = Invoice.update model.credentials act model.invoices
in
({model | invoices = invoices}, Effects.map InvoiceAction fx)
实际操作由发票模块通过功能initialize
提供,其签名为initialize: Credentials -> Action
。这样做是为了保持封装。用户模块不需要知道特定的Invoice操作,只知道有一个与初始化有关,它可以通过该函数获取它。
另外,请注意我已简化更新签名并将通知移到模型中。这是个人偏好,因为我认为通知没有什么特别之处。它们就像模型中的任何其他数据一样。当然,如果通知是通过某个自定义StartApp路由到端口并通过某些JS机制显示的任务,那么将它们保留在返回中可能是有意义的。
答案 1 :(得分:2)
一种方法是:
User
update Invoice
elm-tutorial中的这一章显示了这种模式。