I'm currently working on a task in Angular 9 where I need to create an input field that behaves differently for each letter. However, the main issue I'm facing right now is related to change detection. There seems to be a conflict between two possible solutions. Using changes.subscribe()
with @ViewChildren()
doesn't respond well when I implement a custom trackBy
within my *ngFor
loop. Yet, the trackBy
is crucial to prevent issues with changes in one box affecting another. While I could use the custom trackBy function, it lacks access to data from my Component. Below is the code snippet of my component:
@Component({
selector: 'app-multiple-fields',
templateUrl: './multiple-fields.component.html',
styleUrls: ['./multiple-fields.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => MultipleFieldsComponent),
},
],
})
export class MultipleFieldsComponent
implements OnInit, AfterViewInit, ControlValueAccessor {
@Input() numFields: number = 6;
@ViewChildren('input', { read: ElementRef }) inputs: QueryList<
ElementRef
>;
fields: string[];
onChange: any = () => {};
onTouch: any = () => {};
ngAfterViewInit() {
this.inputs.changes.subscribe((next: QueryList<ElementRef>) => {
let val = next.map((el) => el.nativeElement.value).join('');
this.onChange(val);
this.onTouch(val);
});
}
ngOnInit() {
this.fields = Array(this.numFields).fill('');
}
trackArray(index, item) {
return index;
}
writeValue(value: string) {
if (value.length == this.numFields) this.fields = value.split('');
}
registerOnChange(fn: any) {
this.onChange = fn;
}
registerOnTouched(fn: any) {
this.onTouch = fn;
}
}
Below is the template code for the component:
<input
#input
*ngFor="let item of fields; let i = index; trackBy: trackArray"
[(ngModel)]="fields[i]"
/>
I'm aiming to monitor any changes in the fields[]
array and trigger onChange()
and onTouch()
functions with the combined value for using [(ngModel)]
in the component instance. Any assistance on resolving this issue would be highly appreciated. Thank you!