Issue
In Angular, I have an array of array of numbers, like this one:
[
[1,1,1,1],
[1,1,1,1]
]
I have a ngFor in the HTML that generates the input controls.
<table>
<tbody>
<tr *ngFor="let d of myData">
<td *ngFor="let factor of d; let i = index">
<input type="number" [(ngModel)]="d[i]">
</td>
</tr>
</tbody>
</table>
The problem is that With every keystroke, the focus shifts to the next input on the same row. At the end of that row, it moves out and does not go to the next row.
I do not have any event handlers and the array is static.
Here is the example and you can try it yourself.
- Click inside the top-left input box.
- Type "123".
I see that after the first "jump", the value of the second input is changed on the screen to the one of the first one, but the underlying value of the second element of the array is as before (does not change to the one displayed in the input box).
If I change all elements of the internal array from a type number to an object like this { value: 1}, the weird jumping effect disappears.
Any ideas why this is happening?
Solution
What You have do is use trackBy
https://medium.com/simars/improve-ngfor-usability-and-performance-with-trackby-97f32ab92f1c
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myData = [
[1,1,1,1],
[1,1,1,1]
];
trackByFn(index, item ) {
return( index );
}
}
.title {
font-family: sans-serif;
}
<table>
<tbody>
<tr *ngFor="let d of myData">
<td *ngFor="let factor of d; trackBy: trackByFn; let i = index">
<input type="number" [(ngModel)]="d[i]">
</td>
</tr>
</tbody>
</table>
Array:
<pre>{{ myData | json }}</pre>
Why trackBy?
Angular by default tracks items in a collection by object reference. When we replace the collection with new collection which is not keeping the same objects by reference, Angular can’t keep track of items in the collection even if the objects inside the new collection are same by values, but just clone of previous ones.
Unless trackBy provides a unique id per element in *ngFor iteration, angular will have no knowledge of which items have been removed or added or changed in the new collection.
Answered By - kenny
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.