我有两个操作:验证和更新。两者都可以独立调度,但是我也希望,如果调度update操作,则它首先调度validate操作,并且仅当没有验证时才继续。
如果这是同步代码,则类似于:
if (this.backendService.isValid(dataset)) {
this.backEndService.update(dataset)
}
两个动作(以及它们相应的成功和错误动作)的定义:
export const validateDataset = createAction('[Datasets API] Validate Dataset', props<{ dataset: DataSetDto }>());
export const validateDatasetSuccess = createAction('[Datasets API] Validate Dataset Success', props<{ validationErrors: SgErrorMessage[]}>());
export const validateDatasetFail = createAction('[Datasets API] Validate Dataset Fail', props<{ error: string }>());
export const updateDataset = createAction('[Datasets API] Update Dataset', props<{ dataset: DataSetDto }>());
export const updateDatasetSuccess = createAction('[Datasets API] Update Dataset Success');
export const updateDatasetFail = createAction('[Datasets API] Update Dataset Fail', props<{ errorEntity: SgErrorEntity }>());
尝试1
如果我在监听updateDataset
并尝试先调度validateDataset
时有效果,那么应用.pipe()
似乎永远不会被使用(可能在这里我应该使用类似{ {1}}返回布尔值,而不是也使用hasValidationErrors
运算符):
filter
尝试2
我试图将其拆分为一个updateDataset$ = createEffect(() => {
return this.actions$.pipe(
ofType(DatasetApiActions.updateDataset),
mergeMap(action => of(DatasetPageActions.validateDataset({dataset: action.dataset})).pipe(
withLatestFrom(this.store.pipe(select(getValidationErrors))),
filter(([action, validationErrors]) => validationErrors.length > 0),
mergeMap(([action, validationErrors]) => this.datasetService.editDataSet(action.dataset).pipe(
map(() => DatasetApiActions.updateDatasetSuccess()),
catchError(error => of(DatasetApiActions.updateDatasetFail({error})))
))
))
);
});
操作,该操作应依次调用saveDataset
和validateDataset
操作,并且还过滤updateDataset
以仅在以下情况下运行updateDataset
状态为空。我使用了validationErrors
,所以动作可以顺序触发,可能是触发,但是成功/失败响应稍后出现,因此无法使用验证数据:
concatMap
也许我想的是错误的方式,应该将验证构建为异步表单验证,但是我仍然认为该问题有效。
我正在苦苦挣扎的是,我无法向saveDataset$ = createEffect(() => {
return this.actions$.pipe(
ofType(DatasetPageActions.saveDataset),
concatMap(action => concat(
of(DatasetPageActions.validateDataset({dataset: action.dataset})),
of(DatasetApiActions.updateDataset({dataset: action.dataset}))
))
);
});
updateDataset$ = createEffect(() => {
return this.actions$.pipe(
ofType(DatasetApiActions.updateDataset),
withLatestFrom(this.store.pipe(select(getValidationErrors))),
filter(([action, validationErrors]) => validationErrors.length == 0),
tap(([action, validationErrors]) => console.log("validationErrors: " + validationErrors))
);
}, {dispatch: false});
动作添加效果来触发validateDatasetSuccess
动作,因为它可能由用户单独分派(而不仅仅是通过保存)。有什么办法可以实现这种行为?
答案 0 :(得分:2)
您可以尝试以下方法:
updateDataset$ = createEffect(() => {
return this.actions$.pipe(
ofType(DatasetApiActions.updateDataset),
// dispatch the `validate` action
tap(action => this.store.dispatch(DatasetPageActions.validateDataset({dataset: action.dataset}))),
switchMap(
action => this.store.pipe(
select(getValidationErrors),
// we want to skip the current state
// after all, the store is just a `BehaviorSubject`,
// so subscribing to it will return the current state
skip(1),
filter(validationErrors => /* ... your condition here ... */),
mapTo(action),
),
),
mergeMap(
action => this.datasetService.editDataSet(action.dataset).pipe(
map(() => DatasetApiActions.updateDatasetSuccess()),
catchError(error => of(DatasetApiActions.updateDatasetFail({error})))
)
)
);
});