Angular ngModel внутри ngFor, с конвейером и картой, не работает - PullRequest
1 голос
/ 25 апреля 2020

У меня проблемы в этой ситуации:

@Component({
  selector: 'my-app',
  template: `
    {{items | async| json}}

    <div *ngFor="let item of items | async">
      <input type=checkbox [(ngModel)]="item.b"/>
    </div>
  `
})
export class AppComponent  {
  items = of([{
    name: '1',
  },
  {
    name: '2',
  },
  {
    name: '3',
  }])
  .pipe(map(i=>{
    return i.map(i=>{
      return {
        i: i,
        b: false
      }
    })
  }))
}

Приложение Stackblitz

Проблема в том, что ngModel не работает, и я не вижу изменение свойства b. Если я удаляю канал карты и помещаю логическое свойство в первый массив, все работает. Я что-то пропустил? В чем проблема?

Спасибо

Ответы [ 2 ]

3 голосов
/ 25 апреля 2020

Вы не делаете ничего плохого. Если вы отобразите {{item.b}} в ngFor, вы увидите, что значение корректно меняется между true и false. Как уже упоминалось в другом ответе, это из-за ссылок и обнаружения изменений. Вы также можете просто сохранить наблюдаемые данные в свойстве класса, используя ngOnInit и subscribe:

import { Component } from "@angular/core";
import { of } from "rxjs";
import { map } from "rxjs/operators";

@Component({
  selector: "my-app",
  template: `
    {{ items | json }}

    <form #myForm="ngForm">
      <div *ngFor="let item of items">
        <input [name]="item.i.name" type="checkbox" [(ngModel)]="item.b" />
      </div>
    </form>
  `
})
export class AppComponent {
  items: any[] = [];

  ngOnInit() {
    this.getData().subscribe(data => (this.items = data));
  }

  private getData() {
    return of([
      {
        name: "1"
      },
      {
        name: "2"
      },
      {
        name: "3"
      }
    ]).pipe(
      map(i => {
        return i.map(i => {
          return {
            i: i,
            b: false
          };
        });
      })
    );
  }
}

Вот пример в действии. Не забудьте при необходимости очистить все наблюдаемые, чтобы избежать утечек памяти.

3 голосов
/ 25 апреля 2020

На самом деле то, что вы делаете, правильно. Чтобы проверить, что я имею в виду, измените ваш код следующим образом:

<input type=checkbox (change)="change(item)" [(ngModel)]="item.b"/>

change(item) {
 console.log(item);
}

Это не отражается на dom, потому что массив items сопоставлен с той же ячейкой памяти, и изменение элемента внутри него не приведет к изменению обнаружение в angular для запуска изменения дисплея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...