我正在尝试更新项目,但仅在确认对话框的情况下。我认为这是通过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)。
有人对我如何解决此问题有想法吗?
根据您的描述,我了解的是,当用户单击按钮以更新项目时,您要首先显示一个对话框,如果用户确认,则将向服务器发送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(...)
);
)
);
尝试通过多个操作返回一个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,因此将分派您的两个操作