我有一个警卫,我想确保在页面可视加载之前预先加载数据。我一直关注Todd Motto's strategy,预加载只需要一次发送的数据。
问题是,我的方案需要多个调度,其中一些依赖于其他
。我需要调度加载对象A
,然后我需要使用对象A
上的一些数据来加载对象B
。
为了这个最小的例子,假设我的状态有loading
(布尔值)和things[]
(加载的实体)。当我执行Get
操作时,loading
会翻转为true。 <{1}}在看不见的成功动作时被翻转为假。
loading
虽然第一个工作正常但等待加载&#34;但后续调度不会在下一个&#34;等待之前将我的canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
// fetches the first `thing` with the route's id
this.store.dispatch(new actions.Get(route.params.id));
return this.store
.select(selectState)
.filter(state => !!!state.loading)
.do(state => {
// the first `thing` is loaded
// now use it to load another `thing`
this.store.dispatch(new actions.Get(state.things[0].something));
})
.take(1)
.switchMap(() => this.store.select(selectState))
// in the filter, state.loading is false, even though
// we just fired a dispatch to say it's loading.
// ...because this is checked before the
// dispatch can flip the boolean
.filter(state => !!!state.loading)
.take(1)
.switchMap(() => Observable.of(true))
.catch(() => Observable.of(false));
}
状态变量翻转为true为此加载&#34;检查。
非常感谢任何帮助,或者更好的模式。
答案 0 :(得分:1)
让我们说我的州看起来像这样
{
user: User;
userLoaded: boolean;
userRoles: Role;
userRolesLoaded: boolean
}
我的目标是在加载用户和userRoles之前不加载路由。
假设我已经为getUserLoaded创建了选择器,而getUserRolesLoaded只为我们各自的属性返回了我的状态的布尔值。
这是我加载多个
的方法canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
return this.store.select(getUserLoaded).pipe(
map(loaded => {
// if my user is loaded this will be true
if (!loaded) {
this.store.dispatch(new fromStore.LoadUser());
}
}),
filter(loaded) => loaded),
take(1),
withLatestFrom(this.store.select(fromStore.getUserRolesLoaded)),
map(([nullData, loaded]) => {
if(!loaded) {
this.store.dispatch(new fromStore.LoadUserRoles()
}
}),
withLatestFrom(this.store.select(fromStore.getUserRolesLoaded)),
filter(([data, loaded]) => loaded),
take(1)
);
}
所以这里我首先得到的是我的userLoaded布尔值的状态切片。如果我的用户没有加载,那么我将调度将加载用户的操作。然后我过滤它,以便它不会返回到真,并取一个取消订阅。接下来,我获得了具有getUserRolesLoaded的状态切片,并检查它们是否已加载,如果不是我发送,添加过滤器等待true并取1。
我正在使用rxjs 5.5中引入的管道方法,但是根据您的需要进行转换不应该太难。对我来说,我觉得关键是要了解我选择哪种状态,以确保我检查的是适当加载的数据。
答案 1 :(得分:0)
也许试试这个快速黑客
.take(1)
.switchMap(() => this.store.select(selectState).pluck('loading').distingUntilChanged()
)
只有在从false切换为true时才触发,反之亦然。或者使用中间状态,beforeload-&gt; loading-&gt;加载
答案 2 :(得分:0)
我正在努力查看为什么的代码是否如此工作,以防万一其他人在想:
@ ngrx / store State类使用rxjs watchOn运算符和queueScheduler创建了一个Observable actionsOnQueue。这些排队的动作被馈送到减速器以产生新状态。然后,新状态将发出并触发任何选择器。
第一个分派在解析器的上下文中执行并同步运行。下一行创建一个Observable,该Observable从商店中选择,并立即看到Get操作的效果。因此,筛选器将忽略loading = true的初始状态,并且管道会等待加载完成。
稍后分发并减少成功操作(设置loading = false)时,商店将发出并且过滤器将通过。然后将执行第二次调度。 queueScheduler表示此调度将不会同步执行,因为我们正在“成功”执行调度的内部。
然后,在第二个“获取”操作被简化为状态之前,switchMap将再次订阅商店。