Issue
I'm trying to manage a big input by splitting it into single little inputs and populate the big one with keyup, but for some reason when I fire the keyup event the cursor goes to next little input and duplicates the value. The big input is changed and updated correctly, but little ones have problems. I tried also returning the bigvalue from editValue function, but with same result
html:
<div class="form-group">
<label for="prova">Prova input array</label>
<input type="text" class="form-control form-control-sm" id="prova" placeholder="prova" [(ngModel)]="bigvalue" name="prova" maxlength="100">
</div>
<div class="d-flex flex-row" style="overflow-x: auto">
<div *ngFor="let val of bigvalue | arrayfromstring; let i = index;" class="ml-4 my-3">
<label for="value{{i}}">val{{i}}:</label>
<input type="text" class="form-control form-control-sm" id="value{{i}}" name="inputarrayvals" value="{{val}}" (keyup)="editValue(i, $event, bigvalue)" maxlength="1">
</div>
</div>
ts:
bigvalue = "00000000000000000000000000000000000000000000000"
editValue(i, val, item) {
var vals = item.split('')
if (val.target.value.length > 0)
vals[i] = val.target.value
this.bigvalue = vals.join('')
}
Pipe arrayfromstring used to populate little values:
import{ Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'arrayfromstring'
})
export class ArrayFromStringPipe implements PipeTransform {
transform(string: any) {
return string.split('');
}
}
Solution
You just need a trackBy function
<div *ngFor="let val of bigvalue | arrayfromstring; let i = index; trackBy: trackByFn" class="ml-4 my-3">
trackByFn(index: number, obj: any) {
return index;
}
People say it's for performance but it's also for working with an array of primitive values.
The ngFor
directive is set up to work with arrays of objects. When it generates html nodes it attaches the object to each node as a key, that's how it finds them in the DOM. Supposedly the trackBy function above uses indices as keys.
ngFor
seems to be completely broken when passing in an array of primitive values and no trackBy
function. They seem to be using completely different code when a trackBy function is included.
In fact passing any function to trackBy fixes the odd behaviour, even an empty one.
trackByFn() {}
Or
trackByFn() {
return 'Angular devs please explain';
}
Both work.
Easiest way to reproduce this issue is like this:
export class OneComponent {
array = '000000'.split('');
}
<div *ngFor="let val of array; let i = index">
<input [(ngModel)]="array[i]" />
</div>
and try typing into the inputs.
I reported this as a bug because I think it's pretty janky
https://github.com/angular/angular/issues/45647
Answered By - Chris Hamilton
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.