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 >
<label for="prova">Prova input array</label>
<input type="text" id="prova" placeholder="prova" [(ngModel)]="bigvalue" name="prova" maxlength="100">
</div>
<div style="overflow-x: auto">
<div *ngFor="let val of bigvalue | arrayfromstring; let i = index;" >
<label for="value{{i}}">val{{i}}:</label>
<input type="text" 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('');
}
}
CodePudding user response:
You just need a trackBy function
<div *ngFor="let val of bigvalue | arrayfromstring; let i = index; trackBy: trackByFn" >
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
CodePudding user response:
This might happen because you hold the Shift key to input your numbers.
They keyup event gets fired both for your number key, and the shift key.
Try using the numpad, or locking the shift key before doing so ?
Otherwise, apply a condition into your function to filter non-numerci keys.