我有一个FormArray
里面有不同的FormControl
项目。 我希望能够听到其中任何一个的变化事件。
我试图这样做:
this.form = this.fb.group({
items: this.fb.array([this.fb.control('')])
});
(<FormArray>this.form.get('items')).controls.forEach((control: FormControl) => {
control.valueChanges.subscribe(change => console.log(change));
});
但我似乎从来没有进入console.log
,即使我确信子控件正在触发更改事件(从ControlValueAccessor
界面(。
订阅FormArray
子控件更改的方法是什么?
this.form.get('items').valueChanges.subscribe(changes=> {
console.log(changes)
})
为任何可能在 Google 上找到这个问题的人添加这个。
FormArray
的主要问题是它的子项是动态的,可以添加和删除它们,因此在检测它们的更改之前,我们需要检测FormArray
本身的更改,但只有在添加或删除新子项时,我们才能做到这样的事情:
let length = 0;
let childrenChangesObservable = control.valueChanges.pipe(
filter(() => control.length != length),
switchMap(() => {
length = control.length;
// Here we can detect changes on the new children
})
);
现在要处理对子控件的更改,这里的诀窍是忽略外部可观察childrenChangesObservable
,将其用作订阅并在其中与tap
等运算符一起工作,并检查所有子控件都使用combineLatest
:
// Log each time a child control named "id" changes values
let length = 0;
let childrenChangesObservable = control.valueChanges.pipe(
filter(() => control.length != length),
switchMap(() => {
length = control.length;
return combineLatest(control.controls.map(c => c.controls.id.valueChanges.pipe(
tap(v => console.log("New value", v))
)));
})
);
// We don't care about what comes out of here and when,
// this just handles the subscriptions to the inner observables
childrenChangesObservable.subscribe();
这样,每个内部可观察量中的运算符在需要时执行,但外部操作符仅在所有操作器至少发出一次时才发出,但我们不在乎这一点,因为我们在里面做我们的事情。