NGXS @Select与状态模型一起使用



使用 NGXS@Select装饰器时,访问状态模型上定义的属性的正确方法是什么?

例如,定义了以下状态:

export interface UserStateModel {
firstname: string;
lastname: string;
}
@State<UserStateModel>({
name: 'user',
defaults: {}
})
export class UserState {..}

在组件中,如果我想像这样选择用户状态:

..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 模板中引用该属性,那么我没有任何问题。

有一个关于选择器使用的相关讨论,但我只想确认我对当前版本的期望(如果我做得正确!

我正在使用"@ngxs/store": "^3.0.0-rc.2",

@Select装饰器修饰的可观察量将是模型的数据类型,而不是状态类。 即:

export class MyComponent {
@Select(UserState) user$: Observable<UserStateModel>;
ngOnInit(){
this.user$.subscribe(u => {
//do something with user state
console.log(u.firstname);
});
}   
}

另一个注意事项是,我建议在您的模板中使用异步管道,以便 Angular 为您管理订阅和取消订阅。

看看我刚刚创建的这个可运行的演示项目。

它提供了一个演示,用于从包含books: Book[]BookStateModel中选择allBooks$thickBooks$

注意事项:

  • @Selector()BookState.ts中声明(记忆(,以便可以在其他地方使用。
  • 这些记忆选择器可以通过@Select(Xxx)使用。

希望这有帮助。

您对问题的评论是选择整个状态容器的正确方法。

另一种(在我看来更好的解决方案(是使用根状态模型来推断选择器中的类型。 有了这些,您只能选择必要的状态属性,并且仍然具有类型安全。

我对当前发布的解决方案的看法:

记忆选择器
  • :为您想要选择的每个未修改的状态属性编写记忆选择器会有很大的开销。我还希望记忆选择器有一个小的性能缺点,这可能也是它不是类型问题的官方解决方案的原因。
  • 选择整个状态
  • :非常不方便,因为您很少需要整个状态(例如,在您的示例中,仅选择您的 UserState 的名字(。大多数情况下,您希望选择一个特定的状态属性并将其绑定到视图中或订阅它。您将获得更少的开销和更清晰/更干净的代码。

最新更新