简体   繁体   English

当`ngModelChange`保持值时,Angular ngModel不会更新

[英]Angular ngModel doesn't update when `ngModelChange` keeps value

I have a text field represented as: field = {text: "", valid: false} , and an input with [(ngModel)]="field.text" . 我有一个文本字段表示为: field = {text: "", valid: false} ,以及带[(ngModel)]="field.text"

I want to make that field only accept a defined set of characters (for this issue, numbers), and doing (keypress) doesn't work on mobile, so I did: (ngModelChange)="fieldChanged(field)" 我想打那场只接受一组定义的字符(针对此问题,数字),做(keypress)无法在移动工作,所以我所做的: (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 it's behaviour is extremely weird. 它的行为非常奇怪。

Legend: - input: what key was pressed - before update: first console.log - after update: second console.log - output: what I see on screen in the input 图例: - 输入:按下了什么键 - 更新前:第一个console.log - 更新后:第二个console.log - 输出:我在输入屏幕上看到的内容

| 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 I enter a legal character? 为什么在输入合法字符时它总是更新输出? It should be working for each event call. 它应该适用于每个事件调用。

Edit: Plunker 编辑: Plunker

I think the cause is that modifying the value on ngModelChange breaks change detection, for example if you change the value back to the previous value, because an invalid character was added. 我认为原因是修改ngModelChange上的值ngModelChange中断更改检测,例如,如果将值更改回先前的值,则会添加无效字符。

A 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
}

If anyone having the issues in updating the value, use setTimeout function while updating 如果有人在更新值时遇到问题,请在更新时使用setTimeout函数

// setTimeout function
setTimeout(() => {
  field.text = temp;
  this.cdRef.detectChanges();
}, 1);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM