请让我提供一些背景信息:
在我的应用程序中,我有一个“功能”列表。功能具有 ID 和状态(激活: bool 值)。我在 ngrx 商店内管理这些功能。它基本上是这些功能的数组。这些功能必须从服务器获取,并且可以在运行时更改。该商店会在应用程序启动和其他事件后更新。 Angular 组件观察这些特征。大多数按状态过滤功能(因此大多数只对事件功能感兴趣)。
为了激活某个功能,组件需要调度 ACTIVATE_FEATURE
操作,或者特定的 URL 必须处于事件状态。某些功能在 URL 路径上注册,而其他功能则在 URL 参数上注册。
我已经使用 ngrx router-store 观察到了 URL。 我还能够根据 URL 确定必须激活哪些功能。
现在回答问题:
我正在考虑使用 ngrx 对路由器状态的副作用来激活一项功能,如下所示:
@Effect()
private routerEffect = this.actions$.ofType(ROUTER_NAVIGATION)
然后查看有效负载并分派(dispatch) ACTIVATE_FEATURE 操作,以便我的功能缩减器将给定功能设置为 active: true
。但问题是:如果商店尚未包含该功能怎么办?或者从来没有?如果用户导航到特定的 URL,那么这总是没问题,但如果商店使用与该 URL 匹配的功能进行更新,则该功能应在加载后激活。即使商店仍在加载,也必须可以更改 URL。一旦 URL 不再符合其条件,就必须停用某个功能。
我正在尝试类似的东西,但我根本不知道如何解决这个问题......
@Effect()
private routerEffect = this.actions$.ofType(ROUTER_NAVIGATION)
.map((nav: RouterNavigationAction<fromRouter.State>) => nav.routerState.data.featureIdToActivate)
.withLatestFrom(this.store.select(fromFeatures.selectAllFeatures)) // this store holds an array of features
// now what?? Is this even correct?
// i would need to dispatch something like {type: 'ACTIVATE_FEATURE', payload: featureIdToActivate}
即使我能设法等待商店包含所需的功能,如何在 URL 更改时取消等待?
非常感谢任何建议!谢谢!
最佳答案
下面的内容对您有帮助吗?
@Effect()
router.events
.pipe(
filter(event => event instanceof NavigationEnd) // or whatever you wish
switchMap((event) => {
return store
.pipe(
map((state) => {
const featureId =
getFeatureIdToActivate(event);
return state.features.find(f => f.id === featureId);
}),
filter(feature => feature != null),
map(feature => new ActivateFeatureAction(feature))
);
})
);
在这里,我们正在监听路由器的导航结束事件,或者您想要的任何类型的事件。
对于每个事件,我们将映射切换到商店(意味着任何新事件都会取消旧事件)。
在 switchMap 中,您可以使用逻辑来决定激活哪个功能,因为您同时拥有事件和状态。
然后,只有在找到正确的功能时才调度ActivateFeatureAction。 (我们也在监听商店的声音,因此如果稍后添加某个功能,我们会捕获它)。
关于javascript - ngrx副作用: wait for store data or cancel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49788543/