绑定到状态 - 这是预期的行为吗?
Binding to State - is this expected behaviour?
我有一个包含项目集合的状态:
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
字段 - 当我在该输入字段中键入时,我似乎正在修改该项目的状态,即该项目的 'View Name' 显示是也在变化。
<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>
这是预期的行为吗?我原以为我不会在 'view only' 列表中看到该更改。
或者这只是我做了一些我不应该做的事情 - 我知道我真的应该通过这样的操作将更改发送到商店:
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
谢谢!
这不是错误,这是一个功能 ;)
选择状态的一部分,实际上将return是状态的对象。
这意味着如果您将 属性 更改为其他内容,状态将会更新。
我建议在使用表单时先复制数据,然后再开始使用 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
我有一个包含项目集合的状态:
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
字段 - 当我在该输入字段中键入时,我似乎正在修改该项目的状态,即该项目的 'View Name' 显示是也在变化。
<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>
这是预期的行为吗?我原以为我不会在 'view only' 列表中看到该更改。
或者这只是我做了一些我不应该做的事情 - 我知道我真的应该通过这样的操作将更改发送到商店:
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
谢谢!
这不是错误,这是一个功能 ;)
选择状态的一部分,实际上将return是状态的对象。
这意味着如果您将 属性 更改为其他内容,状态将会更新。
我建议在使用表单时先复制数据,然后再开始使用 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