Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating input affects other input yet there is no binding

Here is my HTML:

<tr *ngFor="let row of formData; let i = index" [attr.data-index]="i">
    <td *ngFor="let rowdata of formData[i]; let j = index" [attr.data-index]="j">
        <input type="checkbox" name="row-{{i}}-{{j}}" [(ngModel)]="formData[i][j]">
    </td>
</tr>

As you can see I've set unique names on the checkboxes to isolate them completely.

formData follows a structure like this:

formData = [
            [false, false],
            [true, true],
            [false, true]
          ]

The form populates correctly.

Checkboxes are generated correctly, however, there is some odd behavior :

When I click the checkbox for the first column, it also checks the box for second column ; this seems like total random behavior, but when I check a box for the second column, it has no affect on the checkbox for the first column

Any ideas why this is happening?

EDIT

Observation: I changed the input to a standard input (not checkbox).

I changed the form values to "true", "false".. instead of true, false.

When I try to change the text in the input, I can only type one character and the input box "deselects" (i.e- I have to keep clicking on the input box to activate it every time I type a character)

EDIT

HTML Output as requested:

enter image description here

like image 998
Dennis Callanan Avatar asked Sep 05 '17 09:09

Dennis Callanan


1 Answers

Using trackBy in the second ngFor made it work for me :

Template :

<tr *ngFor="let row of formData['rows']; let i = index;" [attr.data-index]="i">
    <td *ngFor="let rowdata of formData['rows'][i]; let j = index; trackBy: trackByIndex" [attr.data-index]="j">
      <input type="checkbox" id="row-{{i}}-{{j}}" name="row-{{i}}-{{j}}" [(ngModel)]="formData['rows'][i][j]"/>
    </td>
</tr>

Component :

Define the trackByIndex function :

trackByIndex(index: number, value: number) {
  return index;
}

The reason to use a trackBy is explained here (credit goes to zoechi@github) :

you're iterating the items you're editing and they are primitive values. ngFor can't keep track by identity because when the value changes from 1 to 3 (by editing) it becomes a different identity. Either use a custom trackBy that tracks by index or use objects instead of primitive values.

like image 84
Guillaume Georges Avatar answered Oct 17 '22 01:10

Guillaume Georges