FormControlを@Input
パラメータは、最大値が10である数値タイプの入力にバインドされています。ユーザーがより大きい数値を入力した場合、入力値は変更されません。
イベントの伝播を防止する方法、または古い値を取得して再度設定する方法は何ですか?
私はスタックとgithubから他の多くのソリューションを試しましたが、私の問題は何も解決しません。
valuecontrol: FormControl = new FormControl(0);
constructor(){
this.control.valueChanges.pipe(distinctUntilChanged()).subscribe(newValue=>{
if(newValue >= 10){
// set previous value
const oldValue = this.control.value;
console.log("old value = ", oldValue)
this.control.patchValue(oldValue);
}
})
}.
デモ: https://stackblitz.com/edit/angular-6ocjfj?file=src/app/app.component.ts
valueChanges
イベントは、新しい値がFormControl値に更新された後に発生します。そのため、古い値を取得できません。
最善のアプローチは、@ JB Nizetで言及されているバリデーターを使用することです。
ソリューションを続行したい場合は、Angularの ngDoCheck
ライフサイクルフックを活用して、古い値を保持できます。
変更されたコード:
export class AppComponent implements DoCheck {
private oldValue;
control: FormControl = new FormControl(0);
constructor() {
this.control.valueChanges.pipe(distinctUntilChanged()).subscribe(newValue => {
if (newValue >= 10) {
// set previous value
console.log("old value = ", this.oldValue)
this.control.patchValue(this.oldValue);
}
})
}
ngDoCheck() {
this.oldValue = this.control.value
}
}
1年以上の経験を経て、最適なソリューションを見つけたと思います。この問題を解決するには、pairwise
rxjs operator を使用するのがおそらく最善の方法です。
そのおかげで、ストリームの以前の値を取得できます。
提供されたスニペットは、いくつかの追加手順を必要とするため、元の問題を解決しませんが、「古い値を取得する方法」に関する元の質問を解決します。
これがコードです:
control: FormControl = new FormControl(0);
constructor(){
this.control.valueChanges.pipe(
distinctUntilChanged(),
pairwise() // gets a pair of old and new value
).subscribe(([oldValue, newValue])=>{
console.log(oldValue, newValue)
if(newValue >= 10){
// set previous value
this.control.patchValue(oldValue);
}
})
}
入力コントロールの[max]
属性を10
に設定します。
<input type="number" [max]="10" [formControl]="control">
これにより、newValue >= 10
条件を完全に削除できます。