[英]Why does the oninput event behave differently in Angular than it does in JavaScript?
我正在学习 Angular 和 TypeScript,与 JavaScript 的一些不一致让我感到不安。 这是一个 function 与纯 JavaScript 完美配合(它以编程方式设置输入的min
和max
属性 - 请不要问我为什么我想以编程方式这样做):
function change_number(input,min,max) { if(input.value > max) input.value = max; else if(input.value < min) input.value = min; }
<input type='number' oninput='change_number(this,1,5)' placeholder='Enter a number' />
In Angular and TypeScript, the function behaves strangely: If I enter 10
into the input field, it doesn't reset to 5
, until I enter another digit, meaning the value is only read after the input
event (and not on -input -不知道这是否有意义)。 更奇怪的是它与keydown
和keyup
事件配合得很好。 为什么会有这种行为? 它是否与 Angular 将事件绑定到输入的方式相关联? 我有一种感觉,理解这将有助于我更好地理解 Angular 与NgModel
的绑定机制
仅供参考,这是我在 Angular 中调用 function 的方式(使用 Ionic 框架) - 我使用[(ngModel)]
中的绑定quantity
作为输入值:
<ion-input type='number' (input)='change_numbers(1,5)' [(ngModel)]='quantity'></ion-input>
Angular 框架表现得非常完美。 是我们有点糊涂。
Angular 处理 forms 的方式略有不同。 有两种方法可以在 angular 中构建 forms -
它们之间的主要区别在于上述Sync/async 行为。 简单来说,我们可以这么说。
X
<ion-input type='number' (input)='change_numbers(1,5)' [(ngModel)]='quantity'></ion-input>
以上是一种模板驱动的方法。 这里我们使用[(ngModel)]
,仅在数据更改后才会更新。
为了制作反应输入字段,请使用以下代码:-
在 app.component.ts 文件中
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
@Component({
selector: 'dd-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
form: FormGroup;
min = 0;
max = 5;
constructor(private fb: FormBuilder) {
this.buildForm();
}
buildForm(): void {
this.form = this.fb.group({
numberInput: ''
});
this.form.get('numberInput').valueChanges.pipe(distinctUntilChanged()).subscribe(_ => {
if (_) {
if (_ > this.max) {
this.form.get('numberInput').setValue(5);
}
if (_ < this.min) {
this.form.get('numberInput').setValue(0);
}
} else {
this.form.get('numberInput').reset('');
}
});
}
}
在 app.html 中(这里我发布了 2 种表达方式。)
<form [formGroup]="form">
<!-- <input type='number' [min]='0' [max]='5' formControlName="numberInput" /> we can also this one, more easy just set value dynamically -->
<input type='number' formControlName="numberInput" />
</form>
注意:- 不要忘记导入ReactiveFormsModule
更多关于 forms 的信息可以在官方文档中找到:-https://angular.io/guide/forms-overview
要理解它为什么会这样,首先你需要熟悉两个基本概念:
[(ngModel)]="quantity"
只不过是被翻译成[ngModel]="quantity" (ngModelChange)="quantity = $event"
的糖语法有了这些知识,您就可以了解这里真正发生了什么:
onNgModelChange
被触发, quantity
设置为4
。 input
的内部model值(更具体地说, ngModel
指令)仍然等于undefined
。change_numbers
被调用, quantity
不变。ngModelChange
和change_numbers
都在单个调用堆栈中调用)。 执行变化检测。 因为quantity
(现在4
)绑定到ngModel
(现在undefined
),所以 angular 检测到需要更新 UI(因为undefined != 4
当然)。8
。onNgModelChange
被触发, quantity
设置为48
。 input
(更具体地说, ngModel
指令)的内部model值仍然等于4
。change_numbers
, quantity
更改为5
。quantity
(现在5
)绑定到ngModel
(现在4
),所以 angular 检测到需要更新 UI(因为5 != 4
当然)。7
。onNgModelChange
被触发, quantity
设置为57
。 input
(更具体地说, ngModel
指令)的内部model值仍然等于5
。change_numbers
, quantity
更改为5
。quantity
(现在5
)绑定到ngModel
(现在也是5
),所以 angular 没有检测到需要更新 UI(因为5 == 5
当然)。 一个解决方案可能是在onNgModelChange
方法中调用detectChanges
。 它会起作用,因为此时我们将更新ngModel
的内部model
值(即使它远高于5
)。 因此,即使我们接下来将值减小到5
,angular 仍然会检测到需要更新 UI。
我希望这能解释一切。 如果您有一些问题,请随时告诉我。 干杯!
试试这个,效果很好,如果这不是你想要实现的,请告诉我
html
<input type='number' (change)='change_numbers(1,5)' [(ngModel)]="quantity">
javascript
change_numbers(min,max) {
if(this.quantity > max)
this.quantity = max;
else if(this.quantity < min)
this.quantity= min;
}
不确定这是否有帮助,但我找到了这些;
他们似乎经常谈论使用(input)
; 如果你尝试过?
在谷歌上阅读有关此问题的信息,似乎如果您使用的是 Angular,您必须执行“ Angular 方式”或奇怪的事情,例如您试图寻找答案的事情。
正如 Mandolorian 的 Kuiil 所说; “就是这样”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.