首页 > 解决方案 > Ngrx/effects:如何在通过 http 更新之前显示一个对话框

问题描述

我正在尝试更新项目,但前提是确认对话框。我认为这是通过 ngrx 效果管理此问题的正确方法。

我有一个动作 updateItem,它接收一个项目 ID:

export const updateItem = createAction('...', props<{ id: number }>());

在我的组件中,我使用 ID 调度操作。

我的效果是这样的:

...
updateItem$ = createEffect(() => 
  ofType(ItemActions.updateItem),
  exhaustMap(({id}) => // <-- here i have access to the item id
    this.dialog.open<..., ..., boolean>(...).afterClosed()
  ),
  map(result => result ? result : new ActionItems.DialogClose()),
  switchMap(() => // <-- no access to id, since the result is now a boolean
    // make a http request to update user with id
    this.http.patch<...>(..., [...]).pipe(
      map(...),
      catchError(...)
    );
  )
);
...

现在,当我进行 http 调用时,我无法访问该 ID。如何显示确认对话框,但保留 ID?我考虑过“withLatestFrom”-操作符,但我只希望在对话成功的情况下发生 http 请求。

如果对话成功,我还尝试创建不同的操作,一个分派对话框,第二个分派 updateItem。但即便如此,我还是错过了 id,因为它已经转换了。

我可以将 id 传递给对话框并将 id 作为关闭结果返回,但我实际上希望让我的组件具有展示性。Ngrx/platform 示例做了类似的事情,但它们不需要数据(https://github.com/ngrx/platform/blob/master/projects/example-app/src/app/auth/effects/auth.effects。 ts)。

有谁知道我如何解决这个问题?

标签: angularrxjsangular-materialngrxngrx-effects

解决方案


根据您的描述,我的理解是当用户单击按钮更新项目时,您想先显示一个对话框,如果用户确认,您将向服务器发送一个 http 请求以更新值。假设是这种情况,我在这里给出答案。

如果我必须这样做,我会在 component.ts 中打开该对话框,并在用户确认该对话框时调用该操作以进行 http 调用。你也可以做这样的事情,它更干净。

更新你的component.ts,

updateItem(id: number) {
    this.dialog.open <..., ..., boolean > (...)
    .afterClosed()
    subscribe((confirmed) => {
        if (confirmed) {
            // dispatch your action from here
            this.store.dispatch(updateItem({ id: id }))
        }
    }
}

把你的效果改成这样。

updateItem$ = createEffect(() => 
  ofType(ItemActions.updateItem),
  map(action => action.id),
  switchMap((id: number) => // you should get your id here to make http call
    this.http.patch<...>(..., [...]).pipe(
      map(...),
      catchError(...)
    );
  )
);

推荐阅读