【问题标题】:Passing payload between actions in Angular/Ngrx在 Angular/Ngrx 中的操作之间传递有效负载
【发布时间】:2021-06-28 13:15:09
【问题描述】:

我是 Angular/Ngrx 领域的新手,我在如下应用程序中使用它。我会尽力解释这个问题。

我们有一个包含 2 个组件的主页 - 一个配置页面和一个确认警报(最初是隐藏的)。用户可以更改配置,页面状态存储在MyPageConfig 对象中。单击此页面上的“保存”时,将触发一个操作并显示确认警报。单击警报上的“确认”后,应通过调用后端 API 来保存数据。

我在主页的 HTML 中有这个:

<ng-template #whenLoaded> 
  <configure-page [doSubmitForm]="submitForm"></configure-page>        
  <confirm-delete [remove-config]="removeConfig$" 
            (onCancel)="handleCancel()" (onConfirm)="handleConfirm()"></confirm-delete>            
</ng-template>

removeConfig$ 是一个布尔型 Observable,我正在听,但目前没有使用。

我在主页的 TS 文件中有以下 2 个处理程序:

handleCancelRemove() {
    this.store.dispatch(new actions.CancelRemoval());
}

handleConfirmRemove() {
    this.store.dispatch(new actions.ConfirmRemoval());    
}

请注意,没有有效负载发送到handleConfirmRemove,因为此页面本身不知道配置更改。

在配置页面的doSubmitForm 处理程序中,我将确认消息对话框显示为:

if (some condition) {
    this.store.dispatch(new actions.ShowConfirmationDialog());
    // Here we have the payload and can use it somehow? 
    // But the "confirm" button click is handled in the TS of the main page.
}

它显示对话框。但是我被困在如何传递配置有效负载来持久化它。我可以写一个effect,但为了做到这一点,我需要ConfirmRemoval() 操作来传递恰好在主页上的有效负载。

在我看来,有两种可能的解决方案,但我不知道如何解决它们:

  1. 将有效负载从子(配置)页面传递到父(主)页面,然后它将与确认按钮单击的操作处理程序一起提交。
  2. 让父(主)页面了解配置更改(即表单状态),并使用确认按钮单击的操作处理程序直接创建和提交有效负载。

任何关于如何实现这一点的建议将不胜感激。

【问题讨论】:

    标签: angular typescript ngrx


    【解决方案1】:

    这是非常常见的用例,我实际上会听取确认对话框的结果并采取相应的行动。您通过单个事件总线执行所有操作的事实会混淆逻辑,但这是可行的。

    if (some condition) {
      const payload=wegotthepayload.
      this.showDialog().subscribe(resultOfDialog=>{
          if(resultOfDialog=='okClicked'){
             this.saveThePayloadSomehow(payload);
          }else {
             do something else or ignore.
           }
       }))
    }
    

    其中this.showDialog()是一个打开对话框并返回Observable&lt;ResultOfDialog&gt;的方法

    这可以通过例如在事件总线上发出 Ok/Cancel 事件并过滤事件来完成 (pipe + filter)

    可能是这样的

    showDialog(){
            this.store.dispatch(new actions.ShowConfirmationDialog());
           return this.store.yourEventsStream().pipe(filter(e=>e=='okClicked' || e=='cancelClicked'),take(1));
    

    显然您的对话框必须相应地发出适当的事件。

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 2020-06-24
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 2018-01-06
      • 2022-01-05
      相关资源
      最近更新 更多