Angular ngModel not updating when `ngModelChange` stores value

I have a textbox represented as: field = {text: "", valid: false}

and an input with [(ngModel)]="field.text"

.

I want this field to only accept a specific set of characters (for this problem, numbers) and execution (keypress)

doesn't work on mobile, so I did:(ngModelChange)="fieldChanged(field)"

The method does the following:

fieldChanged(field) {
    console.log(field.text);
    field.text = Array.from(field.text).filter((char:string) => "0123456789".indexOf(char) != -1).join("");
    console.log(field.text);
}

      

And this behavior is extremely strange.

Legend: - input: which key was pressed - before update: first console.log

- after update: second console.log

- output: what I see on the screen at the input

| input   | before update | after update | output |
|---------|---------------|--------------|--------|
| ""      | ""            | ""           | ""     | <- starting position, no event
| "a"     | "a"           | ""           | "a"    |
| "a"     | "aa"          | ""           | "aa"   |
| "4"     | "aa4"         | "4"          | "4"    |
| "a"     | "4a"          | "4"          | "4a"   |
| "a"     | "4aa"         | "4"          | "4aa"  |
| "4"     | "4aa4"        | "44"         | "44"   |

      

Why does it always update the output when a legal character is entered? It should work for every event call.

Edit: Plunker

+5


source to share


1 answer


I think the reason is because the value change in ngModelChange

breaks change detection, for example if you change the value to the previous value because an invalid character was added.

Workaround:



constructor(private cdRef:ChangeDetectorRef) {}

fieldChanged(field) {
    console.log(field.text);
    field.text = Array.from(field.text).filter((char:string) => "0123456789".indexOf(char) != -1).join("");
    console.log(field.text);
    var tmp = field.text;
    field.text = null; // or some other value that normally won't ever be in `field.text`
    this.cdRef.detectChanges();
    field.text = tmp;
    this.cdRef.detectChanges(); // I guess this 2nd call won't be necessary
}

      

+5


source







All Articles