【问题标题】:Angular 4 - Limit user input for specific rangeAngular 4 - 限制特定范围的用户输入
【发布时间】:2018-10-01 07:51:15
【问题描述】:

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

我使用在用户使用输入“箭头”时起作用的 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>();
}

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

如何限制用户在输入组件中输入的内容?

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

【问题讨论】:

  • 您也可以使用自定义管道来实现。
  • 示例项目似乎对我有用。所以我无法复制

标签: angular forms


【解决方案1】:

我不知道错误在哪里,但这应该可以。

   <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>();
    }

【讨论】:

  • 我是否理解我们在这里绕过了角度?我可以以某种方式访问​​角度组件吗?值 99 不固定?
  • 你可以用变量替换99。
  • 这是一个很好的解决方法,但知道它为什么会发生会很有趣
  • 是的。它可能是一个错误。 :)
  • 谢谢,你们俩和@Ashish 都为我提供了可行的解决方案,我不能同时接受。我认为他的解决方案更“棱角分明”,你的更面向 JS。因此,我会支持您的回答,但将他的回答标记为已接受。
【解决方案2】:

我不明白为什么您需要一个 Input 属性 value 用于来自父级的自定义输入。 (可能你想要一些默认值?)。

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

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

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

我是如何解决你的问题的(我使用属性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

【讨论】:

    【解决方案3】:

    如果您希望验证长度,请改用 maxLength。

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

    【讨论】:

    • value 99 只是示例 - 可以是 50 或其他任何东西
    猜你喜欢
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多