Angular 7, jak utworzyć "tymczasowy" model dla pojedyńczego obiektu z listy?

0

Hej.
Robię sobie coś małego na wzór listy zakupów/ todo listy, mam jednak mały problem z modelem. Ogólnie listę renderuję na podstawie tablicy obiektów. Próbuję zrobić taką funkcjonalność, że klikając na edycje elementu w miejscu nazwy i opisu otwiera się formularz z uzupełnionymi polami poprzednim tekstem. Utowrzyłem do tego osobny pojedyńczy obiekt "holder" i połączyłem 2-way-binding tak aby był uzupełniany danymi ze starego modelu podczas kliknięcia edit, ale jeśli użytkownik naciśnie cancel, to pozostają stare niezmienione dane. Niestety coś jest nie tak i nadpisuje się również obiekt w tablicy, w związku z czym po przyciśnięciu 'cancel' na froncie zmiany się zapisują. Co robię źle?

export class AppComponent implements OnInit {
  public products: Product[];
  public isEditMode = false;
  public editionModel: Product;
  public activeIndex: number;


  constructor(private http: HttpClient) {
  }

  ngOnInit(): void {
    this.http.get<Product[]>('products').subscribe(data => this.products = data);
  }

  onCreate(product: Product) {
    this.http.post<Product>('create', product).subscribe(data => this.products.push(data));
  }

  onDelete(productId: number) {
    this.http.delete('delete/' + productId).subscribe(() => {
      this.products = this.products.filter(product => product.productId != productId);
    })
  }

  onUpdate(index: number) {
    console.log('editionModel: ', this.editionModel);
    console.log('product', this.products[index])
  }

  turnOnEdit(index: number, product: Product) {
    this.activeIndex = index;
    this.isEditMode = true;
    this.populateEditionModel(product);
  }

  cancelEdit() {
    this.isEditMode = false;
    this.activeIndex = null;
    this.editionModel = null;
  }

  hasActiveEdition(index: number): boolean {
    return this.activeIndex === index
  }

  private populateEditionModel(product: Product) {
    this.editionModel = product;
  }

}

<div class="card top-buffer" *ngFor="let product of products; let index = index">
        <div class="row">
          <div class="col-md-2">
            Picture here
          </div>
          <div class="col-md-9">
            <div class="row">
              <div class="col-md-12">

                <div class="card" *ngIf="!hasActiveEdition(index)">
                  <div class="card-header">
                    <p><b>{{product.name}}</b></p>
                  </div>
                  <div class="card-body">
                    <p class="card-text">{{product.description}}</p>
                  </div>
                </div>

                <div class="card" *ngIf="hasActiveEdition(index)">
                  <div class="card-header">
                    <input class="form-control" type="text" [(ngModel)]="editionModel.name">
                  </div>
                  <div class="card-body">
                    <textarea class="form-control" type="text" [(ngModel)]="editionModel.description"></textarea>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="col-md-1">
            <div class="row justify-content-start top-buffer">
              <button type="button" class="btn btn-primary" (click)="turnOnEdit(index, product)"
                      *ngIf="!hasActiveEdition(index)">Edit
              </button>
              <button type="button" class="btn btn-outline-primary" (click)="cancelEdit()"
                      *ngIf="hasActiveEdition(index)">Cancel
              </button>
            </div>
            <div class="row justify-content-start top-buffer">
              <button type="button" class="btn btn-secondary" (click)="onDelete(product.productId)" >Delete</button>
            </div>
            <div class="row justify-content-start top-buffer">
              <button type="button" class="btn btn-success" *ngIf="hasActiveEdition(index)" (click)="onUpdate(index)">Save</button>
            </div>
          </div>
        </div>
      </div>
1
this.editionModel = product;

... zapisuje do editionModel referencję do obiektu product - analogicznie dzieje się tutaj:

const objects = [
  { value: 'foo' },
  { value: 'bar' },
];

const firstObject = objects[0];
firstObject.value = 'zar';

console.log(objects); // [ { value: 'zar' }, { value: 'bar' } ]

Aby nie modyfikować oryginalnego obiektu, potrzebowałbyś go sklonować - np. za pomocą Object.assign() czy JSON.parse(JSON.stringify(object)).

0

Ahh tak czułem, a nie sprawdziłem tego :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1