Lord Otori
Lord Otori

Reputation: 349

How to solve checkbox modifying other checkboxes state (not the model)?

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

Upvotes: 0

Views: 45

Answers (2)

wannadream
wannadream

Reputation: 1760

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;
  }

Upvotes: 1

Karl Reid
Karl Reid

Reputation: 2217

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
      },
  ];

Upvotes: 0

Related Questions