Привязка к государству - это ожидаемое поведение? - PullRequest
0 голосов
/ 09 мая 2018

У меня есть состояние, которое содержит коллекцию предметов:

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>

image

Это ожидаемое поведение? Я ожидал, что не увижу это изменение в списке «только для просмотра».

Или это просто тот случай, когда я делаю что-то, чего не должен был делать - я знаю, что действительно должен отправить это изменение через действие в магазин следующим образом:

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

Спасибо!

1 Ответ

0 голосов
/ 09 мая 2018

Это не ошибка, это особенность;)

При выборе части состояния он фактически возвращает объект, являющийся состоянием.

Это означает, что если вы измените свойство на другое, состояние будет обновлено.

Что я хотел бы предложить при работе с формой, так это сделать копию данных до того, как вы начнете изменять ее с помощью 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
...