如何使用RXJS操作符动态合并多个valueChanges可观察对象



我有一个动态表单,像这样。

profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
age: new FormControl(''),
...
});

我想在值改变时做点什么,所以我做了:

this.profileForm.valueChanges.subscribe(() => {
console.log('changed' + this.profileForm.getRawValue());
});

但我不希望整个表单的每一个变化,只是从一些控件,但我不能这样做:

this.profileForm.controls("firstName").valueChanges…

因为我的表单是动态的。所以我尝试在动态方法中创建一个数组,这样就会返回这个

controlsTrigger = ['firstname', 'age'];

注意,它的姓氏不应该触发console.log。

我看到了rxjs

中的合并运算符
merge(
this.form.get("firstname").valueChanges,
this.form.get("age").valueChanges,
).subscribe(() => console.log('changed'));

但是我想把它和动态控制一起使用。

如果您的主要问题是如何将controlsTrigger合并,您可以使用Array.map和扩展操作符:

merge(
...controlsTrigger.map(name => this.form.get(name).valueChanges))
).subscribe(() => console.log('changed'));

合并运算符的问题您无法判断发出的值来自何处,因此您必须映射valueChanges并自己创建关系。所以像这样的代码应该可以达到这个效果:

const controls = ["lastName", "firstName"];
merge(
...controls.map(c =>
this.profileForm.get(c).valueChanges.pipe(map(x => ({ control: c, value: x })))
)).subscribe(console.log);

如果您使用组合最新它将以与传递的可观察对象数组相同的顺序发出值。但是,它只在每个控件至少发出一次时才发出,如果您正在收听formInputs,这不是最佳选择。

我个人更喜欢订阅整个表单的valueChanges,并在您感兴趣的字段包含时执行逻辑,但这取决于您

也许您需要使用组合的管道操作符combinellatest()和withLatestFrom() ?

combineLatest(this.form.get("fieldThatWillTrigger1").valueChanges, this.form.get("fieldThatWillTrigger2").valueChanges).pipe(withLatestFrom(this.form.get("fieldThatWONTTRIGGER1").valueChanges),withLatestFrom(this.form.get("fieldThatWONTTRIGGER2").valueChanges).subscribe(data => {
dosomethinghere();
});

最难的部分是使它动态,所以你需要在我们的

最新更新