NGXS @Select使用状态模型

时间:2018-05-01 01:13:03

标签: angular typescript ngxs

使用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);
     });
   }   
}

我得到了typescript错误,因为firstname上不存在UserState属性(因为它是在相关的模型类型上定义的)。如果我在组件html模板中引用该属性,那么我没有任何问题。

选择器使用方法有related discussion,但我只想确认当前版本的预期(如果我正确地做到这一点!)。

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

3 个答案:

答案 0 :(得分:6)

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

export class MyComponent {

  @Select(UserState) user$: Observable<UserStateModel>;

   ngOnInit(){
     this.user$.subscribe(u => {
         //do something with user state
         console.log(u.firstname);
     });
   }   
}

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

答案 1 :(得分:3)

看看我刚刚创建的runnable demo project

它提供了一个演示,可以从包含allBooks$的{​​{1}}中选择thickBooks$BookStateModel

注意事项:

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

希望这有帮助。

答案 2 :(得分:0)

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

一种替代方法(我认为是更好的解决方案)是使用a root-state model to infer types in Selectors. 使用这些属性,您只能选择必要的状态属性,并且仍然具有类型安全性。

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

  • 已记忆选择器:为要选择的每个未修改状态属性编写一个已记忆选择器会产生很多开销。我也希望记住的选择器在性能上有一个小的缺点,这可能也是为什么它不是types issue.
  • 的官方解决方案的原因
  • 选择整个状态:超级不便,因为您几乎不需要整个状态(例如,在您的示例中,仅选择UserState的名字)。大多数时候,您想选择一个特定的状态属性并将其绑定到视图中或对其进行订阅。您将获得更少的开销,并使代码更清晰/更清晰。