5

使用 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",

4

3 回答 3

13

装饰器装饰的 observable@Select将是模型的数据类型,而不是状态类。IE:

export class MyComponent {

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

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

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

于 2018-05-02T06:54:32.770 回答
5

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

它提供了一个演示来选择allBooks$thickBooks$BookStateModel包含books: Book[].

注意事项:

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

希望这可以帮助。

于 2018-05-02T14:44:59.100 回答
1

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

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

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

  • 记忆选择器:为您想要选择的每个未修改状态属性编写记忆选择器的开销很大。我还希望记忆选择器有一个小的性能缺陷,这可能也是它不是类型问题的官方解决方案的原因。
  • 选择整个状态:超级不方便,因为您很少需要整个状态(例如,在您的示例中,仅选择您的 UserState 的名字)。大多数时候,您希望选择一个特定的状态属性并将其绑定到您的视图或订阅它。您将获得更少的开销和更清晰/更清洁的代码。
于 2019-08-14T12:14:12.627 回答