问题
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