角度4-将用户输入限制为特定范围

时间:2018-10-01 07:51:16

标签: angular forms

我想要一个简单的数字输入组件,该组件仅允许特定范围内的数字。

我使用HTML最小/最大属性,该属性在用户使用输入“箭头”时起作用

<input type="number" style="width: 100px" [(ngModel)]="value" min="0" max="99" />

在将其进一步传播到应用程序时,我也在检查值:

export class AppInput {
  _v: number;

  @Input()
  get value(): number {
    return this._v;
  }
  set value(v) {
    if (v > 99) {
      v = 99;
    }
    this._v = v;
    this.valueChange.emit(v);
  }
  @Output() valueChange = new EventEmitter<number>();
}

当用户直接写输入内容时,例如当值为0时按10-输入正确更改为99。但是,当他继续时,输入内容将更改为990(即使模型正确地为99)。

如何限制用户可以输入的内容?

示例项目:https://codesandbox.io/s/w23900kx05

3 个答案:

答案 0 :(得分:2)

我不在哪里,但应该可以。

   <input type="number" style="width: 100px" [(ngModel)]="value" oninput="this.value = this.value > 99?99:this.value" min="0" max="99" />

如果99不固定

<input type="number" style="width: 100px" 
  [(ngModel)]="value" 
 (keypress)='inputChanged()'
  min="0" max="99" />

.ts文件中

 export class AppInput {
      maxNumber = 50 // u want to only change this;
      maxNumberBackup = this.maxNumber;

      _v: number;

    constructor(){
      this.maxNumber = this.maxNumber -1;
    }
      inputChanged() {
        return this.value > this.maxNumber ? false : true;
      }

      @Input()
      get value(): number {
        return this._v;
      }
      set value(v) {
        if (v > this.maxNumberBackup) {
          v = this.maxNumberBackup;
        }
        this._v = v;
        this.valueChange.emit(v);
      }
      @Output() valueChange = new EventEmitter<number>();
    }

答案 1 :(得分:0)

如果您要验证长度,请使用maxLength代替。

  <input type="text" style="width: 100px" [(ngModel)]="value" maxLength="2" />

答案 2 :(得分:0)

我不明白您为什么需要Input属性value作为来自父级的自定义输入。 (也许您想要一些默认值?)。

解决您的问题。为什么即使模型具有正确的最大值,视图(输入框)也不会更新?让我们这样看:

您有一个属性value,该属性绑定到输入框。因此,当输入值更改时,这就是value's数据将如何更新的方式。考虑最初是value = 0,然后在输入框中输入1,由于2-way bindingvalue将更新为1。是否会在此处将其标记为进行更改检测?是!这将再次在更改检测周期上更新输入框。现在,您输入2(输入框现在包含12)。再次将其标记为更改检测。现在,您输入3(输入应该包含123),但是由于您的逻辑,它被更改为99。那么实际发生了什么变化? value属性中的数据。现在,您的输入框包含99。您输入另一个0。会发生什么?您的设置逻辑将value设置为99。(但请等待它已经是99)。那么它是否标记为更改检测?否。绑定到value的Input会有什么区别吗?不。

注意:对输入框中的所有输入事件,至少应有一个更改检测周期。

我如何解决您的问题(我使用的是属性data而不是value):

constructor(private _cdr: ChangeDetectorRef) {}

@Input() set data(v) {

  this._v = v; // I am assigning whatever value I get to the data property
               // so that in the manual change detection a change can be seen
               // (even though that change doesn't need to be show) 
  this._cdr.detectChanges();
  if (v > 99) {
    v = 99
  }
  else if (v < 0) {
    v = 0
  }
  this._v = v
  this.valueChange.emit(v);
}

在第一步中,我将从输入框中获得的任何值分配给_v,然后在进行逻辑操作之前调用手动更改检测。因此,data的值将由Input Value更新。我的逻辑将其恢复为99 or 0,现在将其标记为进行更改检测,并且您的视图将适当更新(注意:您的输出将自身发出最终值。)

在此处查看工作示例:https://stackblitz.com/edit/angular-custom-number-input?file=src/app/hello.component.ts