Ngrx / effects:在通过http更新之前如何显示对话框

问题描述 投票:0回答:1

我正在尝试更新项目,但仅在确认对话框的情况下。我认为这是通过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 /平台示例执行了类似的操作,但是它们不需要数据(https://github.com/ngrx/platform/blob/master/projects/example-app/src/app/auth/effects/auth.effects.ts)。

有人对我如何解决此问题有想法吗?

angular rxjs angular-material ngrx ngrx-effects
1个回答
0
投票

根据您的描述,我了解的是,当用户单击按钮以更新项目时,您要首先显示一个对话框,如果用户确认,则将向服务器发送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(...)
    );
  )
);

0
投票

尝试通过多个操作返回一个Observable,例如:

updateItem$ = createEffect(() => 
  ofType(ItemActions.updateItem),
  switchMap((id) =>
    const fetchSuccessAction$ = this.http.patch().pipe(map(response => SomeAction({data: response.data}));
    const showDialogAction$ = ShowDialog({id, response});
    return from(fetchSuccessAction$, showDialogAction$);
  )
);

SwitchMap将负责展平返回的Observable,因此将分派您的两个操作

© www.soinside.com 2019 - 2024. All rights reserved.