ngxs - 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 强制执行此规则以确保状态是不可变的,因此如果您在堆栈闪电战中设置developmentMode: true
,当您尝试增加“测试”值时,您将在控制台中看到 NGXS 错误。
要修改计数或测试项目,您需要将操作发送到状态并让状态进行更新(从而将新值发送到您订阅的组件)。这在NGXS 文档中进行了概述。如果您是 NGXS(或 CQRS 模式)的新手,这是一种不同的思维方式。