我有一个使用FormBuilder
构建的简单表单:
this.contactForm = formBuilder.group({
'name': [''],
'email': [''],
'phone': [''],
});
我想观察每个控件的更改,并在发生这种情况时运行带有更新值的函数:
getContacts(value: any) {
this.phoneContacts.findContact(value).then(
contacts => {
// do something
}
);
}
现在,我正在为每个控件执行此操作,使用bind
来访问组件的this
对象:
this.contactForm.get('name').valueChanges.subscribe(this.getContacts.bind(this));
this.contactForm.get('email').valueChanges.subscribe(this.getContacts.bind(this));
this.contactForm.get('phone').valueChanges.subscribe(this.getContacts.bind(this));
有没有办法只需一次订阅即可观察更改并获得更新后的价值?我知道我可以直接订阅this.contact.form
,但是我不是只更新控件而是将所有控件都作为值。
答案 0 :(得分:5)
您可以使用merge运算符将3个单独的observable合并为一个。这将为您提供单个observable,只要任何一个表单字段值发生更改,就会发出单个值。
this.contactForm.get('name').valueChanges
.merge(this.contactForm.get('email').valueChanges)
.merge(this.contactForm.get('phone').valueChanges)
上述方法的主要问题是您现在不知道哪个值与哪个表单控件有关。一种解决方案是将值更改映射到另一个包含值和控件(即值的来源)的对象
// making some local variables for convenience
let name = this.contactForm.get('name')
let email = this.contactForm.get('email'
let phone = this.contactForm.get('phone')
name.valueChanges.map(v => ({control: name,value: v})
.merge(email.valueChanges.map(v => ({control: email, value: v}))
.merge(phone.valueChanges.map(v => ({control: phone, value: v}))
这将给出一个可观察的,只要任何字段发生变化就会发出,它发出的值将是一个包含值的对象和发出该值的控件。
答案 1 :(得分:0)
您可以将valueChanges用于单个控件并订阅它:
[
{ "op": "add", "path": "/foo", "value": "bar"},
{ "op": "replace", "path": "/baz", "value": "boo" }
]
答案 2 :(得分:0)
您可以从表单中获取所有控件valueChanges并合并所有流:
const observablesArray = this.contactFrom.controls.map((control) => control.valueChanges);
Observable.merge(...observablesArray).do(console.log).subscribe();
现在,当字段更改时,您会收到一个值,而不是一个包含所有字段的对象。
答案 3 :(得分:-1)
foreach(Control control in Controls)
{
if (control is Label)
{
((Label)control).Font = f;
}
}
OR
你可以像这样定位个人控制,
foreach (Label label in Controls.OfType<Label>())
{
label.Font = f;
}