Elm中组件之间的通信

Elm中组件之间的通信,elm,Elm,假设我试图遵循Elm体系结构,并在使用StartApp时将我的工作流分为Users和Invoices 用户有发票,但他们必须登录才能访问发票 模型可能类似于以下内容: 类型模型 =NotLoggedIn凭证 |LoggedIn RealName(可能是发票) 类型别名状态= {login:Model ,通知:。。。。。。 , ...... 类型别名发票={发票:列出发票,…} 用户模块具有以下操作: 类型动作 =登录(结果Http.Error字符串) |注销 |提交 ... 和更新功能: 更

假设我试图遵循Elm体系结构,并在使用
StartApp
时将我的工作流分为
User
s和
Invoice
s

用户有发票,但他们必须登录才能访问发票

模型可能类似于以下内容:

类型模型
=NotLoggedIn凭证
|LoggedIn RealName(可能是发票)
类型别名状态=
{login:Model
,通知:。。。。。。
, ......
类型别名发票={发票:列出发票,…}
用户模块具有以下操作:

类型动作
=登录(结果Http.Error字符串)
|注销
|提交
...
和更新功能:

更新:操作->模型->(模型、效果操作、通知)
更新操作用户=
案例(行动、用户)
(登录资源)——>
案件
确定名称->
(LoggedIn name Nothing,Effects.none,信息“欢迎!”)
...
我跳过了身份验证的细节,一切都很好。有趣的部分是
Login
操作。元组被发送到
main
中的
step
函数:

步骤:动作->状态->(状态,效果动作)
步进动作状态=
案例诉讼
用户操作a->
let(newstate,ef,n)=User.update a state.login
在({state | login=newstate,notification=n},Effects.map UserAction ef)中
发票行动a->。。。。。。
因此,用户已登录。接下来,我们要在
发票
模块中调用一些
init
操作

但这应该如何正确完成?如何启动
发票
的操作以保留封装?我是否应该返回除
效果以外的其他效果。无

一种方法是:

  • 在父组件中创建邮箱
  • 将该邮箱的地址传递给
    User
    update
  • “用户更新”将返回一个向该地址发送消息的效果
  • 收到消息后,此邮箱将触发流向
    发票的操作

中的本章显示了这种模式。

这可能是一种可以通过对应用程序数据进行不同建模来解决的情况

按照我的理解,您有需要作为用户的操作和不需要用户的操作。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
。这样做是为了维护封装。用户模块不需要知道特定的发票操作,只需要知道有一个与初始化相关的操作,并且可以通过该函数获取该操作离子


另外,请注意,我已经简化了更新签名并将通知移动到模型中。这是我个人的偏好,因为我认为通知没有什么特别之处。它们与模型中的任何其他数据块一样。当然,如果通知是通过某个自定义StartApp路由到端口并通过对于一些JS机制,将它们保留在回报中可能是有意义的。

感谢您的宝贵见解。