在我的应用中,我有user.component
和college.component
。
在user.component
和store
中,我得到了用户列表
this.store.dispatch(new LoadUsers());
this.users$ = this.store.select(UserSelector.getAllUsers)
this.users$.subscribe(...)
在college.component
上,我也需要商店中的该用户,因此我将其称为同一派遣
this.store.dispatch(new LoadUsers());
this.users$ = this.store.select(UserSelector.getAllUsers)
this.users$.subscribe(...)
我叫相同的this.store.dispatch(new LoadUsers());
是因为,如果我在首页加载打开的大学页面时,没有存储的用户,则需要给他们打电话。
如果我第一次打开users.component
,我会吸引用户,但是当我进入大学页面后,
我收到错误消息
无法读取未定义的属性“数据” 为用户。
在这种情况下处理这种存储的最佳方法是什么?
检查数据是否在存储和调用分派中存在,或对每个组件的loadUsers()
采取相同的动作/减少器/效果?
Thnx
答案 0 :(得分:2)
如果您的用户数据变化很大,则可以重新加载。如果您的用户数据通常是静态的,那么多次调用是不明智的,因为这只会无缘无故地使您的应用变慢。
要解决单个加载问题,有两种方法。您应该在实体上保留一个已加载的参数,然后在成功加载时将化简器中的已加载值设为true。
您现在可以订阅该已加载的值,如果它为false,则分派负载,如果为true,则不分派调用。这种方法使效果更简单,但是您的容器将具有更长/更丑陋的代码。
constructor(private store: Store<fromAuth.State & fromData.State>){
this.users$ = this.store.select(UserSelector.getAllUsers);
}
ngOnInit() {
this.store.select(UserSelector.getUsersLoaded).subscribe(value =>
if (!value) this.store.dispatch(new LoadUsers());
);
}
一种更平滑的方法是将您的代码保持不变,并进行检查以确保效果。 (邓肯·亨特(Duncan Hunter)在ngrx的Pluralsights课程上对我答复)(ref. to ngrx course on pluralsight)
这种方法可以使您的代码在容器中更整洁,但会使效果复杂化。
两条路线均可行,您可以选择自己喜欢的路线。
我也想参考NGRX团队提供的fantastic demo应用程序,这是ngrx方法的灵感之源。 (但是他们没有在那里解决您的问题)。
答案 1 :(得分:0)
如果您对同一个实体两次执行API调用,使用存储的目的是什么?
据我说,您不应两次调用用户API。您应尽量减少API调用,以向客户提供非常轻松和高效的用户体验。
为此,我建议您在状态中添加loaded
和loading
两个新字段,然后创建一个选择器isInitialised
,如下所示:
export const getUsersInitialised = (state: State) => state.loaded || state.loading;
然后仅当未加载用户或已经有其他任何组件正在加载用户时加载用户,
getUsers(): Observable<User[]> {
const users = this.store.select(getAllUsers);
this.store.select(getUsersInitialised).pipe(take(1), filter(v => !v)).subscribe(() => {
this.store.dispatch(new LoadUsers());
});
return users;
}
这样,用户API仅在未加载用户时被调用一次,并且在加载后每次都会从商店本身返回用户。
注意-
true
true
,并将已加载状态更改为false
。