I've created a Plunker.
The code is here:
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<button (click)="changeArrayToOne()">ChangeOne</button>
<button (click)="changeArrayToTwo()">ChangeTwo</button>
<table>
<tr>
<td *ngFor="let c0 of array" contenteditable='true'>
{{c0}}
</td>
</tr>
</table>
</div>
`,
})
export class App {
name:string;
initial = [];
one = [];
two = [];
array = [];
constructor() {
this.initial = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
this.one = [4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0];
this.two = [4,4,4,5,0,0,0,0,0,0,0,0,0,0,0,0];
this.array = this.initial.slice();
}
changeArrayToOne() {
this.array = this.one.slice();
}
changeArrayToTwo() {
this.array = this.two.slice();
}
}
`
I'm trying to create editable table that is populated by array with ngFor
. I use contenteditable='true'
attribute for that.
Table is being populated with this.array
variable.
I also have two buttons ChangeOne
and ChangeTwo
, which replace all values of this.array
with values from arrays this.one
and this.two
.
So, here are steps to reproduce the problem:
this.initial
array).0
. Change it to 10
(remember, table is editable).ChangeOne
. It will replace this.array
values from this.initial
to this.one
.As you can see, the first three elements were replaced with 4
's and the 10
has moved to the fourth position.
If you'll press ChangeTwo
or ChangeOne
again, the 10
will just move to the right.
Why?! And how can it be fixed? I don't want 10
to be present at all after I replace the array.
Here is a Plunker to show how it works. The code to use is this :
customTrackBy(index, item) {
return index + '-' + item;
}
HTML :
*ngFor="let c0 of array; trackBy: customTrackBy"
Because you array is made of primtive values, you have to tell Angular how to check for changes. Since the value changes, you have to return the item, and if you have an issue with the index, you have to return the index too.
See this as a custom way of creating IDs for your array.