0

I have a for that goes over elements in a array of Boolean variables and uses each Boolean as a model for a checkbox.

The models array looks like this:

  models = [true,false,true,true,false,false,true];

The template looks like this:

<h1>Hello {{name}}</h1><br>
<div *ngFor="let mod of models; let i=index">
    <input [(ngModel)]="models[i]" type="checkbox">
</div>
<pre>{{models|json}}</pre>

When I click a checkbox, a random element changes its state too. Not sure if this is a bug or I'm just not understanding something.

How do I make this checkboxes behave appropriately?

Complete example showing this behavior: https://plnkr.co/edit/siTXHoIF3OuXnZd37yir?p=preview

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Lord Otori
  • 349
  • 1
  • 4
  • 17
  • You need to refer to this:http://stackoverflow.com/questions/39347773/how-to-set-bindings-in-ngfor-in-angular-2 – wannadream May 03 '17 at 18:36
  • See plunker: https://plnkr.co/edit/fXPfLTnotRgX2cm1jGyB?p=preview – wannadream May 03 '17 at 18:45
  • @wannadream You have found the solution I was looking for. Would you please post an answer so I can accept it? (PS: could you add
    {{models|json}}
    to your plunker so the UI looks the same to mine and people spot the difference more easily?)
    – Lord Otori May 03 '17 at 18:58

2 Answers2

1

Please see my edited plunker: https://plnkr.co/edit/fXPfLTnotRgX2cm1jGyB?p=preview

Basically, you need to track object in ngFor: How to set bindings in ngFor in Angular 2?

In template:

<h1>Hello {{name}}</h1><br>
<div *ngFor="let mod of models; let i=index,trackBy:trackByIndex">
    <input [(ngModel)]="models[i]" type="checkbox" (click)="onClick(i)">
</div>
<pre>{{models}}</pre>

In component.ts:

  trackByIndex(index: number, obj: any): any {
    return index;
  }
Community
  • 1
  • 1
wannadream
  • 1,669
  • 1
  • 12
  • 14
0

I modified your code to use an array of objects as the model instead of an array of plain booleans. That's seems a bit more idiomatic to me, and it fixes your problem.

With this approach too you could add stuff like a label field and other information to the model for each checkbox, and use that in your template, so in general I think this is a better way of handling things.

There's probably a better way of approaching this using Angular 2, but I'm really not familiar with it myself, sorry.

https://plnkr.co/edit/8561HPbx7hDcHsTVq1C4?p=preview

models = [
      {
        selected : true
      },
      {
        selected : false
      },
      {
        selected : true
      },
      {
        selected : true
      },
      {
        selected : false
      },
      {
        selected : false
      },
      {
        selected : true
      },
  ];
Karl Reid
  • 2,147
  • 1
  • 10
  • 16