使用NGX和状态管理的开放模式

时间:2019-07-01 07:17:12

标签: angular modal-dialog state ngxs

我想使用NGXS打开模式,该模式将为数据表设置列可见性。

这是我的代码:

state.ts文件:

@Action(OpenColumnModal)
openColumnModal(ctx: StateContext<FeedStateModel>) {
    const state = ctx.getState();
    const allCols = state.allColumns;
    return this.modalService.openColumnVisibilityModal(allCols).pipe(tap((result) => {
        ctx.setState({
            ...state,
            allColumns: result,
            userColumns: result.filter(col => col.visible)
        });
    })
}

modal.service.ts:

openColumnVisibilityModal(columns): Observable<any> {
    const dialogRef = this.dialog.open(ColumnVisibilityModal, {
        data: columns,
        autoFocus: false,
        hasBackdrop: true,
        disableClose: true
    });

    return dialogRef.afterClosed();
}

当我使用NGXS打开的模式时,关闭后不会发出state事件。之后,我需要单击某处以调用openColumnModal函数内的回调函数。

我正在使用Angular Material对话框。

有人知道关闭模式后如何自动调用回调函数吗?

提前感谢:)

3 个答案:

答案 0 :(得分:0)

尝试使用订阅代替管道:

@Action(OpenColumnModal)
openColumnModal(ctx: StateContext<FeedStateModel>) {
    const state = ctx.getState();
    const allCols = state.allColumns;
    return this.modalService.openColumnVisibilityModal(allCols).subscribe(result => {
        ctx.setState({
            ...state,
            allColumns: result,
            userColumns: result.filter(col => col.visible)
        });
    })
}

答案 1 :(得分:0)

要添加到Armen的分析器中:管道用于链接不同的函数并返回Observable。管道内使用Tap来产生副作用(例如记录管道之间的值以进行调试等)。

签出this RxJS docs page,您可以阅读:

Note: this is different to a subscribe on the Observable. If 
the Observable returned by tap is not subscribed, the side 
effects specified by the Observer will never happen. tap 
therefore simply spies on existing execution, it does not 
trigger an execution to happen like subscribe does.

换句话说:如果您不订阅管道返回的可观察,该管道将根本无法运行。您的解决方法:

return this.modalService.openColumnVisibilityModal(allCols).subscribe((result) => {
    ctx.setState({
        ...state,
        allColumns: result,
        userColumns: result.filter(col => col.visible)
    });
});

答案 2 :(得分:0)

P.S。 -建议在动作处理程序中订阅的其他答案不正确,因为NGXS不能这样工作!

您当前的方法是正确的,问题是动作处理程序在Angular区域之外运行。只需将NgZone类注入您的状态并在Angular的区域内执行代码即可:

constructor(private modalService: ModalService, private zone: NgZone) {}

@Action(OpenColumnModal)
openColumnModal(ctx: StateContext<FeedStateModel>) {
  const state = ctx.getState();
  const allCols = state.allColumns;
  return this.zone.run(() =>
    this.modalService.openColumnVisibilityModal(allCols).pipe(
      tap(result => {
        ctx.setState({
          ...state,
          allColumns: result,
          userColumns: result.filter(col => col.visible)
        });
      })
    )
  );
}

当您调度任何操作时-NGXS使用runOutsideAngular在父区域内为此操作调用适当的处理程序,这是设计使然。

您还可以查看executionStrategy option,它允许提供自己的类或使用现有的NoopNgxsExecutionStrategy,而根本不使用NgZone类。