【问题标题】:How to force ngModel update when value did not change?当值没有改变时如何强制更新ngModel?
【发布时间】:2018-01-14 18:51:02
【问题描述】:

我想将数字输入限制在 0-100 范围内,但在输入时,而不是在验证期间。我正在使用 ngModel 绑定值并发出更改事件:

<input [ngModel]="value" (ngModelChange)="validate($event)" />

然后检查值是否超过给定的限制:

public validate(value) {
    if (value > 100)
        this.value = 100;
    if (value < 0)
        this.value = 0;
}

这部分有效。但是,如果我说尝试输入 150 并且值将切换到 100,那么我可以输入任何超过 100 的值,因为模型值仍然是 100,因此输入值不会更新。有没有办法手动强制更新?

编辑:我在这里错过了非常重要的一点。这种行为似乎只发生在 type=number 的输入中。文本输入不会超过 100。我的解决方法是 Faisal 建议使用带有 preventDefault 的 keypress 事件,如下所示:

public keyPress(event) {
    let inputChar: number = +String.fromCharCode(event.charCode);
    if (this.value + inputChar > 100 || this.value + inputChar < 0) {
        // Exceeded limits, prevent input
        event.preventDefault();
    }
}

【问题讨论】:

    标签: angular angular2-ngmodel


    【解决方案1】:

    您可以添加 else 部分以反映更改。

    public validate(value){
        if(value>100)
            this.value=100;
        else
            this.value = value    
    }
    

    【讨论】:

    • 模型值是正确的,但是由于它没有改变(如果模型值是100,我输入1000,它仍然是100)输入字段没有更新以反映这个模型。
    【解决方案2】:

    另一种方式..据我所知,使用 NgZone(相当于 AngularJs $scope.$apply()).. 喜欢:

    constructor(private _ngZone:NgZone){
    
    }
    
    
    public validate(value){
        if(value>100)
            this.value=100;
        if(value<0)
            this.value=0;
    
    this._ngzone.run(()=>{
     this.value=(value>100) ? 100  ? (value<0) ? 0 : 0;
    });
    
    }
    

    【讨论】:

      【解决方案3】:

      使用正则表达式来限制用户输入。

      这是您输入的 html 代码:

      <input [(ngModel)]="value" 
             (keypress)="keyPress($event)"
             (ngModelChange)="validate($event)"  
              maxlength=3 />
      

      .. 和打字稿代码:

      keyPress(event: any) {
          const pattern = /[0-9]/;
          let inputChar = String.fromCharCode(event.charCode);
      
          if (!pattern.test(inputChar)) {
              // invalid character, prevent input
              event.preventDefault();
          }
      }
      
      validate(value:number) {
          if(value>100) {
              this.value=100;
          }
      }
      

      这是一个正常工作的插件:Plunker DEMO

      【讨论】:

      • 这不适用于输入类型号,但是如果我检查按键是否模型值+输入字符超过 100,它似乎正在修补我所拥有的。不是真正干净的解决方案,但有效。谢谢。
      【解决方案4】:

      我遇到了同样的问题,但找到了一个我更喜欢的不同解决方案。正如您所说,问题在于模型中的值在您的功能之前和之后是相同的。 我所做的是在更改值之前调用 Angular 的更改检测,以便它注册更改。为此,请使用 ChangeDetectorRef 类并调用其 detectChanges 方法。

      因此,您的函数变为:

      public validate(value) {
          this.changeDetector.detectChanges();
          if (value > 100)
              this.value = 100;
          if (value < 0)
              this.value = 0;
      }
      

      而且效果很好。希望对您有所帮助。

      【讨论】:

      • 谢谢@Romain。比禁用所有箭头键和退格的选定解决方案要好得多。使用您的解决方案,我设法构建了一个非常好的格式化输入。
      • 非常感谢!复选框也有同样的问题,试图在 change 方法中更改复选框的值。节省了我 3 个小时的搜索时间!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 2021-05-25
      • 2011-04-21
      • 2019-06-29
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      相关资源
      最近更新 更多