我的 angular 應用程式中有表單組。由于我想避免為每個表單元素撰寫 onChange,我的想法是訂閱整個表單更改,然后在事件檢查更改元素
所以這是代碼的相關部分:
constructor(){
this.orderForm = this.formBuilder.group({
...
});
this.event$ = this.orderForm.valueChanges.subscribe((x:any) => {
console.log('form value changed')
console.log(x)
});
問題是,這個 x 只是整個表格,所以我不知道改變了什么元素
有什么聰明的方法可以找出更改的表單元素嗎?
uj5u.com熱心網友回復:
如果您有一個只有表單控制元件、沒有嵌套組或 FormArrays 的簡單表單,這很有效。
您可以merge對每個表單控制元件值更改使用 rxjs并找出哪個更改了:
merge(
...Object.keys(this.orderForm.controls).map(
(controlName: string) =>
this.orderForm.get(controlName).valueChanges.pipe(
tap((value) => {
console.log(`Control "${controlName}" changed. New value: ${value}`)
})
)
)
).subscribe();
這是一個STACKBLITZ供您參考。
uj5u.com熱心網友回復:
“偷”了AT82的想法,我們可以有一個遞回函式,回傳一個observable。好吧,我們可以使用 map 來回傳具有兩個屬性的物件,而不是使用“tap”:名稱(控制元件已更改)和值。
所以有些喜歡
mergeForm(form: FormGroup | FormArray, sufix: string) {
if (form instanceof FormArray) {
console.log(sufix)
const formArray = form as FormArray;
const arr = [];
for (let i = 0; i < formArray.controls.length; i ) {
const control = formArray.at(i);
arr.push(
control instanceof FormGroup
? this.mergeForm(control, sufix i '.')
: control.valueChanges.pipe(
map((value) => ({ name: sufix i, value: value }))
)
);
}
return merge(...arr);
}
return merge(
...Object.keys(form.controls).map((controlName: string) => {
const control = form.get(controlName);
return control instanceof FormGroup || control instanceof FormArray
? this.mergeForm(control, sufix controlName '.')
: control.valueChanges.pipe(
map((value) => ({ name: sufix controlName, value: value }))
);
})
);
}
我們可以順便打電話
this.mergeForm(this.orderForm, '')
.pipe(takeWhile((_) => this.alive))
.subscribe((res) => {
console.log(res);
});
你可以看到stackblitz
注意:如果你不使用 FormArray 你可以簡單地使用遞回函式
uj5u.com熱心網友回復:
我不認為有一個函式只回傳已更改的 formControl。
但是由于 valueChanges 是一個可觀察的,您可以pairwise用來獲取上一個和下一個值。并比較它們以找出發生了什么變化。
this.orderForm.valueChanges
.pipe(startWith(null), pairwise())
.subscribe(([prev, next]: [any, any]) => ... );
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/382662.html
上一篇:打字稿:從函式引數中選擇鍵
