Angular 2 - 在Observable

时间:2016-10-11 06:40:22

标签: angular angular2-forms

我有一个使用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,但是我不是只更新控件而是将所有控件都作为值。

4 个答案:

答案 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;
}