Подтвердить что ты не робот

Angular2 ngМодель против переменных ngFor

Возможно ли (или еще не возможно) использовать ngModel для значений из ngFor? Является ли Angular пытаться защитить меня от плохой производительности?

Отлично работает: http://jsfiddle.net/langdonx/n5pjgev6/

<input type="text" [(ng-model)]="value">{{value}}

Не работает так хорошо: http://jsfiddle.net/langdonx/n5pjgev6/1

<li *ng-for="#name of names">
    <input type="text" [(ng-model)]="name">{{name}}
</li>

ИСКЛЮЧЕНИЕ: Невозможно переназначить имя привязки переменных

Я также попытался привязать к массиву, который... вроде работает, но захватывает фокус, а также генерирует исключение: http://jsfiddle.net/langdonx/n5pjgev6/2/

<li *ng-for="#name of names; #i = index">
    <input type="text" [(ng-model)]="names[i]">{{name}}
</li>

ИСКЛЮЧЕНИЕ: LifeCycle.tick называется рекурсивно

Edit:

Я могу обойти проблему LifeCycle.tick, используя более прямой подход, но фокус все равно украден, потому что ngFor перерисовывает вещи: http://jsfiddle.net/langdonx/n5pjgev6/3/ p >

<li *ng-for="#name of names; #i = index">
    <input type="text" [value]="names[i]" (input)="names[i] = $event.target.value">{{names[i]}}
</li>
4b9b3361

Ответ 1

Я думаю, что ngFor не нравится отслеживать элементы массива, которые являются примитивными значениями, имеющими ngModel.

Если вы удалите ngModel внутри цикла, он работает.

Он также работает, когда я обновляю jsfiddle с помощью

this.names = [{name: 'John'}, {name: 'Joe'}, {name: 'Jeff'}, {name: 'Jorge'}];

и

<li *ng-for="#n of names"><input type="text" [(ng-model)]="n.name">{{n.name}}</li>

Ответ 2

Решение состоит в том, чтобы ссылаться на значение внутри ngModel по его индексу. Поэтому [(ngModel)]="names[index]".

Но этого недостаточно, потому что *ngFor отслеживает элементы по значению. Как только значение будет изменено, старое значение не может быть отслежено. Поэтому нам нужно изменить функцию отслеживания, чтобы вернуть индекс, таким образом trackBy: trackByIndex.

Эта проблема объясняется здесь.

Решение:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <input type="text" 
        *ngFor="let name of names; let nameIndex = index; trackBy: trackByIndex"
        [(ngModel)]="names[nameIndex]"/>
      <br/>
      {{ names | json }}
    </div>
  `,
})
export class App {

  names: string[];

  constructor() {
    this.names = ['a', 'b', 'c'];
  }

  public trackByIndex(index: number, item) {
    return index;
  }
}