首页 > 解决方案 > NGXS 选择器或选择器注释返回是按值传递还是引用传递?

问题描述

ngxs 传递对象的方式是什么?我有以下状态

@State<CounterStateModel>({
  name: 'counter',
  defaults: { count: 0, isLoading: true, tests: [{value: 0}] }
})

和选择器

@Selector() 
  static count(state: CounterStateModel) {
    return state.count;
  }

  @Selector() 
  static test(state: CounterStateModel) {
    return state.tests;
  }

我在 component.ts 中使用了这两个选择器

  @Select(CounterState.test) test$: Observable<TestModel[]>;
  @Select(CounterState.count) count$: Observable<number>;

然后在模板中我显示值

<div class="count" *ngFor="let test of (test$ | async)">TEST: {{ test?.value }}</div>
<div class="count">COUNT: {{ (count$ | async) }}</div>

然后我通过订阅并直接加1来增加计数或值

  incrementT() {
    this.test$.subscribe(test => test.map(t => t.value++))
  }

  incrementC() {
    this.count$.subscribe(count => count++)
  }

单击按钮后,测试数组元素中的值增加,但计数保持不变。那么 NGSX 传递了什么?查看 stackblitz 网址:

https://stackblitz.com/edit/ng-ngxs-playground-pmekh1?file=src/app/counter/counter.component.ts

标签: ngxs

解决方案


要改变包含在状态中的值,您需要将操作发送到状态,而不是修改您在订阅中收到的值。

NGXS 强制执行此规则以确保状态是不可变的,因此如果您在堆栈闪电战中设置developmentMode: true,当您尝试增加“测试”值时,您将在控制台中看到 NGXS 错误。

在此处输入图像描述

要修改计数或测试项目,您需要将操作发送到状态并让状态进行更新(从而将新值发送到您订阅的组件)。这在NGXS 文档中进行了概述。如果您是 NGXS(或 CQRS 模式)的新手,这是一种不同的思维方式。


推荐阅读