store已有缓存数据如何取消ngrx效果?
How to cancel the ngrx effect if the store has already the cached data?
在我的 Angular 应用程序中,如果商店已经有数据,我想停止使用 ProductService
调用服务器,其中有 http
。
这是我目前拥有的。我从商店获取流并检查商店是否有产品。如果商店已经有产品,return 该数据。否则继续流程,获取 categoryId
,使用 ProductService
和 return 数据调用服务器。
我做的效果对吗?
loadProducts$ = createEffect(
() => ({ debounce = 300, scheduler = asyncScheduler } = {}) =>
this.actions$.pipe(
ofType(ProductActions.LoadProducts),
debounceTime(debounce, scheduler),
switchMap(() => this.ProductStore.pipe(select(ProductSelectors.selectAllProducts))),
switchMap((Products) => {
if (Products.length != 0) {
return ProductActions.LoadProductsSuccess({ Products });
}
return of(ProductActions.LoadProductsCancelled({ Products }));
}),
switchMap(() => this.store.pipe(select(fromRoots.getCategory))),
switchMap((category) =>
this.ProductService.getProducts(category.categoryId).pipe(
map(Products => (ProductActions.LoadProductsSuccess({ Products }))),
catchError(err => of(ProductActions.LoadProductsFailed(err))
)
))));
你可以像这样使用条件效果
@Effect()
getMemberInfo$: Observable<Action> = this.actions$
.ofType<memberAction.GetMember>(
memberAction.MemberActionTypes.GetMember
)
.switchMap((action) => {
let obs;
this.store.select(getMember).take(1).subscribe(res => {
const existsInStore = res.length > 0;
if (existsInStore) {
let member: IMember = res.find(x => x.id === action.payload);
member = {
...member
};
obs = new memberAction.GeMemberSuccess(member);
} else {
obs = this.memberService.getMember(action.payload)
.map(member => {
return new memberAction.GeMemberSuccess(member);
});
}
});
return obs;
});
我根据 Flignats 的建议更新了效果,如下:
loadProducts$ = createEffect(
() => ({ debounce = 300, scheduler = asyncScheduler } = {}) =>
this.actions$.pipe(
ofType(ProductActions.LoadProducts),
debounceTime(debounce, scheduler),
withLatestFrom(
this.store.select(ProductSelectors.selectAllProducts),
this.rootState.select(fromRoots.getcategory),
),
switchMap(([action, existingProducts, category]) => {
if (existingProducts.length > 0) {
return of(ProductActions.LoadProductsSuccess({ Products: existingProducts }));
}
return this.ProductService.getProducts(category.categoryId).pipe(
map(newProducts => (ProductActions.LoadProductsSuccess({ Products: newProducts }))),
catchError(err => of(ProductActions.LoadProductsFailed(err)))
)
})));
在我的 Angular 应用程序中,如果商店已经有数据,我想停止使用 ProductService
调用服务器,其中有 http
。
这是我目前拥有的。我从商店获取流并检查商店是否有产品。如果商店已经有产品,return 该数据。否则继续流程,获取 categoryId
,使用 ProductService
和 return 数据调用服务器。
我做的效果对吗?
loadProducts$ = createEffect(
() => ({ debounce = 300, scheduler = asyncScheduler } = {}) =>
this.actions$.pipe(
ofType(ProductActions.LoadProducts),
debounceTime(debounce, scheduler),
switchMap(() => this.ProductStore.pipe(select(ProductSelectors.selectAllProducts))),
switchMap((Products) => {
if (Products.length != 0) {
return ProductActions.LoadProductsSuccess({ Products });
}
return of(ProductActions.LoadProductsCancelled({ Products }));
}),
switchMap(() => this.store.pipe(select(fromRoots.getCategory))),
switchMap((category) =>
this.ProductService.getProducts(category.categoryId).pipe(
map(Products => (ProductActions.LoadProductsSuccess({ Products }))),
catchError(err => of(ProductActions.LoadProductsFailed(err))
)
))));
你可以像这样使用条件效果
@Effect()
getMemberInfo$: Observable<Action> = this.actions$
.ofType<memberAction.GetMember>(
memberAction.MemberActionTypes.GetMember
)
.switchMap((action) => {
let obs;
this.store.select(getMember).take(1).subscribe(res => {
const existsInStore = res.length > 0;
if (existsInStore) {
let member: IMember = res.find(x => x.id === action.payload);
member = {
...member
};
obs = new memberAction.GeMemberSuccess(member);
} else {
obs = this.memberService.getMember(action.payload)
.map(member => {
return new memberAction.GeMemberSuccess(member);
});
}
});
return obs;
});
我根据 Flignats 的建议更新了效果,如下:
loadProducts$ = createEffect(
() => ({ debounce = 300, scheduler = asyncScheduler } = {}) =>
this.actions$.pipe(
ofType(ProductActions.LoadProducts),
debounceTime(debounce, scheduler),
withLatestFrom(
this.store.select(ProductSelectors.selectAllProducts),
this.rootState.select(fromRoots.getcategory),
),
switchMap(([action, existingProducts, category]) => {
if (existingProducts.length > 0) {
return of(ProductActions.LoadProductsSuccess({ Products: existingProducts }));
}
return this.ProductService.getProducts(category.categoryId).pipe(
map(newProducts => (ProductActions.LoadProductsSuccess({ Products: newProducts }))),
catchError(err => of(ProductActions.LoadProductsFailed(err)))
)
})));