/ / Wiążenie z państwem - czy to oczekiwane zachowanie? - kątowe, ngxs

Wiązanie z państwem - czy to oczekiwane zachowanie? - kątowe, ngxs

Mam stan, który zawiera kolekcję przedmiotów:

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}
]
});
}

}

Mój komponent jest zasubskrybowany do listy elementów w sklepie, gdy dodaję nowy element, który jest odzwierciedlony na wyświetlonej liście (wszystko dobrze).

Obserwowane zachowanie

Następnie wiążę ten wyświetlany element do input pole - kiedy wpisuję to pole wejściowe, wydaje mi się, że modyfikuję stan tego elementu, tzn. zmienia się również wygląd "Wyświetl nazwę" elementu.

<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>

obraz

Czy to oczekiwane zachowanie? Spodziewałem się, że zmiana nie zostanie odzwierciedlona na liście "tylko widok".

A może to tylko przypadek, w którym robię coś, czego nie powinienem robić? Wiem, że naprawdę powinienem wysłać tę zmianę przez akcję do sklepu w ten sposób:

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

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

Testuję to za pomocą

* ngxs: 3.0.1
* @angular/core: 6.0.0

Zobacz pełne repo próbki tutaj https://github.com/garthmason/ngxs

Dzięki!

Odpowiedzi:

1 dla odpowiedzi № 1

To nie jest błąd, to jest funkcja ;)

Wybierając kawałek stanu, on faktycznie zwróci obiekt, który jest stanem.

Co oznacza, że ​​jeśli zmienisz właściwość na coś innego, stan zostanie zaktualizowany.

To, co chciałbym zasugerować podczas pracy z formularzem, polega na tym, że tworzysz kopię danych przed rozpoczęciem zmiany za pomocą ngModel.

podczas korzystania z formularzy reaktywnych istnieje funkcja o nazwie PatchValue, która to zrobi. https://angular.io/guide/reactive-forms#patchvalue

Jeśli chodzi o zwykłe formularze, musisz to zrobić ręcznie.

lodash ma funkcję o nazwie cloneDeep, która powinna ci pomóc https://lodash.com/docs#cloneDeep

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

var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false