0

我有一个包含项目集合的状态:

import { State, Action, StateContext } from '@ngxs/store';
import {AddItem} from './app.actions';

export interface Item { 
  id: number;
  name: string;
}

export interface AppStateModel { 
   items: Item[];
}

@State<AppStateModel>({
  name: 'app',
  defaults: {
    items: []
  }
})
export class AppState { 

  @Action(AddItem)
  addItem(ctx: StateContext<AppStateModel>, action: AddItem){
     const state = ctx.getState();

        ctx.patchState({
            items: [
                ...state.items,
                { id: action.id, name: action.name}
            ]
        });
  }

}

当我添加一个反映在显示列表中的新项目时,我的组件订阅了商店中的项目列表(一切正常)。

观察到的行为

然后,我将该显示的项目绑定到一个input字段 - 当我在该输入字段中键入时,我似乎正在修改该项目的状态,即该项目的“查看名称”显示也在发生变化。

<ng-container *ngIf="app$ | async as app">

Name: <input #name />
<button (click)="addItem(name.value)">Add Item </button>

<br/>
<br/>

Items List:

<div *ngFor="let item of app.items">
  View Name: <span>{{item.name}}</span>
</div>

<br/>

Items List 2 with updates:

<div *ngFor="let item of app.items">
  Update Name: <input [(ngModel)]="item.name" />
</div>

</ng-container>

图片

这是预期的行为吗?我原以为我不会在“仅查看”列表中看到该更改。

或者这只是我做我不应该做的事情的一个例子 - 我知道我真的应该通过这样的操作将更改发送到商店:

Update Name: <input [ngModel]="item.name" (ngModelChange)="updateItem(item.name)" />

updateItem(value) {
   this.store.dispatch(new UpdateItemAction(value));
}

我正在测试这个

* ngxs: 3.0.1
* @angular/core: 6.0.0

在此处查看完整的示例回购https://github.com/garthmason/ngxs

谢谢!

4

1 回答 1

2

这不是一个错误,这是一个功能 ;)

选择国家的一部分时,实际上将返回状态的对象。

这意味着如果您将属性更改为其他内容,则状态将得到更新。

在使用表单时,我建议您在开始使用 ngModel 更改数据之前制作数据副本。

当使用响应式表单时,有一个名为 patchValue 的函数可以执行此操作。 https://angular.io/guide/reactive-forms#patchvalue

当涉及到普通表格时,您将不得不手动完成。

lodash 带有一个名为 cloneDeep 的函数,它应该可以帮助你 https://lodash.com/docs#cloneDeep

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
于 2018-05-09T07:16:52.197 回答