Angular 2 - Get the value of changed FormControl in Observable

ぃ、小莉子 提交于 2019-12-12 23:20:06

问题


I have a simple Form built with FormBuilder:

this.contactForm = formBuilder.group({
  'name': [''],
  'email': [''],
  'phone': [''],
});

I want to watch every control for changes, and run a function with the updated value when this happens:

getContacts(value: any) {
    this.phoneContacts.findContact(value).then(
        contacts => {
            // do something
        }
    );
}

Right now, I'm doing this for every control, using bind to have access to the this object of the component:

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));

Is there any way to watch for changes and have the updated value with just one subscription? I know I can subscribe directly to this.contact.form, but then instead of just the updated control I get all controls as the value.


回答1:


You can merge the 3 individual observables into one using the merge operator. That will give you a single observable that emits the single value any time any one of the form field values changes.

this.contactForm.get('name').valueChanges
    .merge(this.contactForm.get('email').valueChanges)
    .merge(this.contactForm.get('phone').valueChanges)

The main problem with the approach above is that you now don't know which value goes with which form control. One solution is to map the value changes into another object that contains both the value and the control (i.e. the source of the value)

// 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}))  

This will give an observable that emits whenever any of the fields change, and the value it emits will be an object containing the value and the control that emitted that value.




回答2:


You may use valueChanges for single control and subscribe to it :

 this.contactForm.controls['name'].valueChanges.subscribe((value) => {
  console.log(" name : " + value)
})



回答3:


You can get all controls valueChanges observable from the form and merge all the stream:

const observablesArray = this.contactFrom.controls.map((control) => control.valueChanges);

Observable.merge(...observablesArray).do(console.log).subscribe();

Now you receive a value and not an object with all the fields when the field change.




回答4:


ngOnInit() {
    this.contactForm.valueChanges.subscribe(value => {
      console.log(value.name)  
    });
}

OR

you can target individual control like this,

this.contactForm.controls.name.valueChanges.subscribe(value => {
     console.log(value);
});


来源:https://stackoverflow.com/questions/39971679/angular-2-get-the-value-of-changed-formcontrol-in-observable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!