Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 ngModel bind in nested ngFor

Tags:

angular

I'm attempting convert an Angular 1 app to Angular 2. Looping through a jagged array of booleans (boolean[][]). I'm rendering out checkboxes with the following code:

<div *ngFor="#cell of CellData; #parentIndex = index">
    <input *ngFor="#col of cell; #childIndex = index" type="checkbox" [(ngModel)]="CellData[parentIndex][childIndex]" />      
</div>

The checkboxes display correctly, however, if I select a checkbox the one to the right of it is also selected.

This logic works fine in the Angular 1 app so I'm not sure if it's a problem with the way I am using ngModel or an issue with Angular 2.

Any help would be much appreciated

like image 378
Scott Lyons Avatar asked Apr 07 '16 07:04

Scott Lyons


1 Answers

Update

The official way to use ngForTrackBy seems to be

      <input 
          *ngFor="let col of cell; let childIndex=index; trackBy:customTrackBy" 
          type="checkbox" 
          [(ngModel)]="CellData[parentIndex][childIndex]" />      

See http://angularjs.blogspot.co.at/2016/04/5-rookie-mistakes-to-avoid-with-angular.html for more details

note the : in trackBy:customTrackBy

original

You can use *ngForTrackBy for this:

@Component({
  selector: 'my-app', 
  template: `
    <div *ngFor="let cell of CellData; let parentIndex = index">
      <input 
          *ngFor="let col of cell; let childIndex = index" type="checkbox" 
          *ngForTrackBy="customTrackBy" 
          [(ngModel)]="CellData[parentIndex][childIndex]" />      
    </div>

    Data:<br/><br/>
    {{CellData | json}}
  `
})
export class AppComponent {
  constructor() {
    this.CellData = [
      [ true, false, true, false ],
      [ false, true, false, true ]
    ]
  }

  customTrackBy(index: number, obj: any): any {
    return index;
  }
}

Angular by default tracks the object identity but different trues and falses have the same identity. Without *ngForTrackBy Angular looses track which true or false is at which position. With *ngForTrackBy="customTrackBy" we make *ngFor use the index instead of object identity.

Plunker example

See also

  • https://github.com/angular/angular/issues/4402
like image 156
Günter Zöchbauer Avatar answered Sep 16 '22 23:09

Günter Zöchbauer