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

Posted

技术标签:

【中文标题】NGXS @Select 与状态模型一起使用【英文标题】:NGXS @Select usage with state model 【发布时间】:2018-10-11 02:54:29 【问题描述】:

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

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

关于选择器的使用有一个related discussion,但我只是想确认一下我对当前版本的期望(以及我是否正确地执行此操作!)。

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

【问题讨论】:

我现在想知道是否正确的方法是将我的选择器声明为@Select(UserState) user$: Observable&lt;UserStateModel&gt; 【参考方案1】:

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

export class MyComponent 

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

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

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

【讨论】:

感谢@Mark 从我之前的评论中确认。回复:异步管道,是的,一直在尽可能地使用它。我正在现有的 Angular 应用程序上尝试 NGXS,因此在组件模板中使用管道,但我有一些服务是订阅者,所以我认为我需要在那里手动订阅(没有模板)。【参考方案2】:

看看我刚刚创建的这个runnable demo project。

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

注意事项:

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

希望这会有所帮助。

【讨论】:

感谢您的演示链接! 无价之宝。谢谢。【参考方案3】:

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

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

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

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

【讨论】:

以上是关于NGXS @Select 与状态模型一起使用的主要内容,如果未能解决你的问题,请参考以下文章

NGXS Devtools 不代表当前状态

NGXS updateItem 状态算子

NGXS 状态不变

ngxs、redux 开发工具显示之前的状态

ngxs:在 Action 中访问不同的状态

我们应该取消订阅 ngxs Selector 吗?