【问题标题】:Input control value is not updated properly from ngModelChange输入控件值未从 ngModelChange 正确更新
【发布时间】:2019-09-23 09:13:43
【问题描述】:

我在用户键入时更新输入时遇到问题。

我需要从用户那里获取如下所示的代码:354e-fab4(2 个字母数字组,每组 4 个字符,用“-”分隔)。用户不应该键入'-',它会自动插入。 当用户键入的内容与用于验证的正则表达式不匹配时,我想恢复到以前的有效值。

问题是验证失败时输入中的值没有正确更新。另一方面,如果我设置了一个硬编码字符串,则该值会反映在输入中。

我在 stackblitz 中隔离了问题:https://stackblitz.com/edit/angular-qsbtiz

您可以通过输入超过 8 个字符来重现该问题:正则表达式测试失败,代码设置为之前的值,但该值未反映在 HTML 输入中。

这是当输入值改变时调用的方法:

onCodeChange(newValue: string) {
    const previousValue = this.code;
    this.code = newValue;
    const regex = new RegExp(/^([a-z0-9]{0,4})?(-)?([a-z0-9]{0,4})?(-)?$/);

    // If the code doesn't match the regex, revert to the old value and return.
    if (!regex.test(newValue)) {

        // This changes this.code, but it's not reflected in the input's value.
        this.code = previousValue;

        // This changes this.code and it is reflected in the input's value.
        //this.code = '1234';
    } else {
        const groups = regex.exec(newValue);
        if (!groups[2] && groups[3]) {
            this.code = `${groups[1]}-${groups[3]}`;
        }
    } 
}

请注意,我对这段代码有什么问题感兴趣,而不是对使用自定义屏蔽输入组件等替代解决方案感兴趣。

谢谢。

【问题讨论】:

    标签: javascript angular


    【解决方案1】:

    自从你分裂[(ngModel)]。我建议通过将它自己的元素传递给 onCodeChange() 函数来设置它: Stackbliz example

    在模板中:

    <input #input type="text" placeholder="" (ngModelChange)="onCodeChange($event,input)" [ngModel]="code"/>
    

    在您的 TS 文件中:

      code = '';
      previousValue = ''
    
      onCodeChange(newValue: string, input) {
        this.code = newValue;
        const regex = new RegExp(/^([a-z0-9]{0,4})?(-)?([a-z0-9]{0,4})?(-)?$/);
    
        if (!regex.test(newValue)) {
          console.log("No match. Reverting the code to the previous value (this is not working as expected).");
          input.value = this.previousValue;
        } else {
          const groups = regex.exec(newValue);
          if (!groups[2] && groups[3]) {
            this.code = `${groups[1]}-${groups[3]}`;
          }
          //Save previousValue here instead
          this.previousValue = this.code
        } 
      }
    

    【讨论】:

    • 谢谢,伊桑。这似乎是答案。但是,我很好奇为什么我的代码被破坏了?属性绑定不应该处理值设置吗?
    • 这是因为当你拆分[(ngModel)]时,你必须自己进行绑定,(ngModelChange)事件发射器不会为你设置值,它只会发出事件,如以及 [ngModel] 仅将值绑定到 TS,而不是向后绑定。
    • 我认为是相反的(或者我可能误解了你的评论......):[ngModel]="code" 表示当code 发生变化时,输入值会发生变化。 [(ngModel)]="code" 的等价物是 &lt;input [ngModel]="code" (ngModelChange)="code = $event" /&gt;。这就是为什么我不明白为什么在我的onCodeChange() 版本中,对this.code 的一些分配反映在输入中,而另一些则没有。
    • 对我来说,我真的没有绝对的答案,但是如果您查看下面 ngModel 指令的实际代码,从第 221 行开始,然后按照它到文件 shared.ts 到第 153 行,我相信函数isPropertyUpdated() 总是返回false,除了第一次更改,我认为这是导致问题的原因。 github.com/angular/angular/blob/master/packages/forms/src/…
    【解决方案2】:

    如果你想恢复以前的值,那么你应该声明previousValue并像这样分配值。

    https://stackblitz.com/edit/angular-vdqbxz

    我将onModelchange 事件更改为keyup,因为这些组由于某种原因没有正确生成(IMO 与这篇文章无关)。

    【讨论】:

    • 感谢您的代码。确实,它有效,但是对于讨厌的打字效果(出现和删除不被接受的字符之间的延迟)可以做些什么呢?另外,初始代码不能正常工作的解释是什么?
    猜你喜欢
    • 2021-08-04
    • 1970-01-01
    • 2019-04-24
    • 2020-03-31
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    相关资源
    最近更新 更多