【问题标题】:How do I pass data from MatDialog => Rxjs Effect => Component?如何从 MatDialog => Rxjs Effect => Component 传递数据?
【发布时间】:2020-03-15 05:28:45
【问题描述】:

我的组件正在调用一个动作并使用@Effect 打开对话框。 对话框将数据发送回@Effect。我可以在@Effects 中使用 .afterClosed() 查看数据,但我不知道如何使用 .afterClosed() 将其发送到组件。

这是组件调用对话框的方式:

this.store.dispatch(new fromWorkspace.ShowDialog());

这是效果中的对话框:

  @Effect({ dispatch: false })
   showDialog$ = this.actions$.pipe(
    ofType(WorkspaceActionTypes.ShowDialog),
    map(action => {
      this.dialogRef = this.addPersonDialog.open(PersonSelectorComponent, {
        disableClose: false,
        hasBackdrop: true,
        restoreFocus: true,
        data: { }
      });
      // I can see the data here;
      this.dialogRef.afterClosed().subscribe(result => console.log(result));
    })
  );

以下是 Dialog 发送数据的方式:

constructor(@Inject(MAT_DIALOG_DATA) public data: any,
              public dialogRef: MatDialogRef<PersonSelectorComponent>) { }


 addPerson(event: MatAutocompleteSelectedEvent) {
    if (event.option.selected) {
      const person = event.option.value;
      if (person) {
      this.dialogRef.close(person);
      // data is correct here;
      console.log(person);
      }
    }

回到组件这里是我尝试使用 .afterClose() 的方式:

public dialogRef: MatDialogRef<PersonSelectorComponent>


//this does not work
this.assigneeDialogRef.afterClosed().subscribe(result => console.log(result));

【问题讨论】:

  • 尝试在 stackblitz 创建一个演示,以便更快地解决它。

标签: angular rxjs dialog store dialogresult


【解决方案1】:

因此,继续使用行动/减速器方法,我执行以下操作:

  • 创建了一个新操作“addPerson/addPersonSuccess”(以避免订阅从对话框返回的数据。
  addPerson$ = this.actions$.pipe(
    ofType(WorkspaceActionTypes.AddPerson),
    map(action => {
      return new AddPersonSuccess(action.payload);
    }),
    catchError(error => this.dispatchErrorHandleActions(new addPersonFailure(error),
            `Couldn't add person. Please try again later.`))
  );
  • 然后在reducer中处理:
 case WorkspaceActionTypes.AddPersonSuccess:

      return update(state, {
        person: {
          data: { $set: action.payload }
        }
      });
  • 并且在 reducer 中也包含了一个 Selector:
export const addPerson = createSelector(getWorkspaceState, (state: WorkspaceState) => state.person);
  • 然后回到组件中在构造函数中调用它:
 this.person$ = this.store.select(fromWorkspace.addPerson);
  • 现在我可以通过订阅 'this.person$' observable 来获取数据。

【讨论】:

    【解决方案2】:

    通常,您会从效果中调度一个带有结果数据的操作,这些数据将通过您的减速器,然后最终进入您的数据存储。从那里您的组件将订阅数据存储(通过选择器)并以这种方式获取更新的数据。

    如果您使用效果直接获取数据并将其返回到您的组件而不将其放入存储中,那么我根本不会使用效果。我只是直接调用对话框并获得结果并用它做我想做的事。

    【讨论】:

    • 感谢您的回复。您的意思是将我目前在 Effect 中的一段代码移动到 Component 中,如下所示? ``` showDialog$ = this.actions$.pipe( ofType(WorkspaceActionTypes.ShowDialog), map(action => { this.dialogRef = this.addPersonDialog.open(PersonSelectorComponent, { disableClose: false, hasBackdrop: true, restoreFocus: true , data: { } }); // 可以看到这里的数据; this.dialogRef.afterClosed().subscribe(result => console.log(result)); }) ``
    • 你不需要任何动作的东西,因为那是用于ngrx的,所以它就像:this.dialogRef = this.addPersonDialog.open(PersonSelectorComponent, { disableClose: false, hasBackdrop: true, restoreFocus: true, data: { } }); // I can see the data here; this.dialogRef.afterClosed().subscribe(result =&gt; console.log(result));
    • 感谢您的建议。我决定采用调度动作/减速器方法。它就像一个魅力。 :)
    猜你喜欢
    • 2017-08-12
    • 1970-01-01
    • 2023-03-26
    • 2021-04-09
    • 1970-01-01
    • 2017-11-03
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多