NGXS @Select 与状态模型的用法
NGXS @Select usage with state model
当使用 NGXS @Select
装饰器时,访问状态模型上定义的属性的正确方法是什么。
例如定义了以下状态:
export interface UserStateModel {
firstname: string;
lastname: string;
}
@State<UserStateModel>({
name: 'user',
defaults: {}
})
export class UserState {..}
在组件中,如果我想 select 像这样的用户状态:
..export class MyComponent {
@Select(UserState) user$: Observable<UserState>;
ngOnInit(){
this.user$.subscribe(u => {
//do something with user state
console.log(u.firstname);
});
}
}
我收到打字稿错误,因为 firstname
属性 在 UserState
上不存在(因为它是在相关模型类型上定义的)。如果我在组件 html 模板中引用 属性 那么我没有任何问题。
有 related discussion 围绕 select 或用法,但我只是想确认我对当前版本的期望(以及我是否正确执行此操作!)。
我正在使用 "@ngxs/store": "^3.0.0-rc.2",
由 @Select
装饰器装饰的 observable 将属于模型的数据类型,而不是状态 class。即:
export class MyComponent {
@Select(UserState) user$: Observable<UserStateModel>;
ngOnInit(){
this.user$.subscribe(u => {
//do something with user state
console.log(u.firstname);
});
}
}
另一个注意事项是,我建议在您的模板中使用异步管道,以便 Angular 为您管理订阅和取消订阅。
看看我刚刚创建的这个runnable demo project。
它从包含 books: Book[]
.
的 BookStateModel
提供 select allBooks$
和 thickBooks$
的演示
注意事项:
@Selector()
在 BookState.ts
中声明 (memoized) 以便它可以在其他地方使用。
- 这些记忆的 select 可以通过
@Select(Xxx)
使用。
希望对您有所帮助。
您对问题的评论是 select 整个状态容器的正确方法。
另一种方法(在我看来是更好的解决方案)是使用 a root-state model to infer types in Selectors.
使用那些你可以 select 只有必要的状态属性并且仍然具有类型安全性。
我对当前发布的解决方案的看法:
- Memoized Selectors:编写一个 memoized select 或每个您想要 select 的未修改状态属性的开销很大。我还希望 memoized selectors 有一个小的性能缺陷,这可能也是为什么它不是 types issue.
的官方解决方案的原因
- 选择整个状态:超级不方便,因为您很少需要整个状态(例如,在您的示例中,select 仅需要您的用户状态的名字)。大多数时候,您希望 select 一个特定的状态属性并将其绑定到您的视图或订阅它。您将获得更少的开销和更清晰/更清晰的代码。
当使用 NGXS @Select
装饰器时,访问状态模型上定义的属性的正确方法是什么。
例如定义了以下状态:
export interface UserStateModel {
firstname: string;
lastname: string;
}
@State<UserStateModel>({
name: 'user',
defaults: {}
})
export class UserState {..}
在组件中,如果我想 select 像这样的用户状态:
..export class MyComponent {
@Select(UserState) user$: Observable<UserState>;
ngOnInit(){
this.user$.subscribe(u => {
//do something with user state
console.log(u.firstname);
});
}
}
我收到打字稿错误,因为 firstname
属性 在 UserState
上不存在(因为它是在相关模型类型上定义的)。如果我在组件 html 模板中引用 属性 那么我没有任何问题。
有 related discussion 围绕 select 或用法,但我只是想确认我对当前版本的期望(以及我是否正确执行此操作!)。
我正在使用 "@ngxs/store": "^3.0.0-rc.2",
由 @Select
装饰器装饰的 observable 将属于模型的数据类型,而不是状态 class。即:
export class MyComponent {
@Select(UserState) user$: Observable<UserStateModel>;
ngOnInit(){
this.user$.subscribe(u => {
//do something with user state
console.log(u.firstname);
});
}
}
另一个注意事项是,我建议在您的模板中使用异步管道,以便 Angular 为您管理订阅和取消订阅。
看看我刚刚创建的这个runnable demo project。
它从包含 books: Book[]
.
BookStateModel
提供 select allBooks$
和 thickBooks$
的演示
注意事项:
@Selector()
在BookState.ts
中声明 (memoized) 以便它可以在其他地方使用。- 这些记忆的 select 可以通过
@Select(Xxx)
使用。
希望对您有所帮助。
您对问题的评论是 select 整个状态容器的正确方法。
另一种方法(在我看来是更好的解决方案)是使用 a root-state model to infer types in Selectors. 使用那些你可以 select 只有必要的状态属性并且仍然具有类型安全性。
我对当前发布的解决方案的看法:
- Memoized Selectors:编写一个 memoized select 或每个您想要 select 的未修改状态属性的开销很大。我还希望 memoized selectors 有一个小的性能缺陷,这可能也是为什么它不是 types issue. 的官方解决方案的原因
- 选择整个状态:超级不方便,因为您很少需要整个状态(例如,在您的示例中,select 仅需要您的用户状态的名字)。大多数时候,您希望 select 一个特定的状态属性并将其绑定到您的视图或订阅它。您将获得更少的开销和更清晰/更清晰的代码。