[英]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.