Je bricole avec des formes réactives et une abonnement valueChanges
dans Angular 2. Je ne comprends pas très bien pourquoi certaines formes d’abonnement semblent interdites.
this.form.get('name').valueChanges /* <- doesn't work */
.do(changes => {
console.log('name has changed:', changes)
});
.subscribe();
this.form.get('title').valueChanges.subscribe( /* <- does work */
changes => console.log('title has changed:', changes)
);
Ce pilote reproduit le problème (ouvrez la console DevTools pour voir l'erreur):
ZoneAwareError {stack: "Erreur: Non capturé (promis): TypeError: Ne peut pas se…g.com/[email protected]/dist/zone.js: 349: 25) []", message: "Uncaught (in promesse): TypeError: Impossible de définir le fichier… ore.umd.js: 8486: 93) ↵ dans Array.forEach (native) ", originalStack:" Erreur: Non capturé (dans la promesse): TypeError: Impossible de se… ps: // unpkg .com/zone.js @ 0.7.5/dist/zone.js: 349: 25) ", zoneAwareStack:" Erreur: Non capturé (promis): TypeError: Impossible de se se situer.com/[email protected] /dist/zone.js:349:25) [] ", nom:" Erreur "…}
Le premier motif (avec do
) n'est-il pas illégal?
Cela a fait fonctionner votre plunker:
import 'rxjs/add/operator/do';
.do (changes => { console.log ('nom a changé:', modifications) })
App.ts complet modifié
import {Component, NgModule, OnInit} from '@angular/core'
import {BrowserModule } from '@angular/platform-browser'
import { FormGroup, FormBuilder, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/do';
@Component({
selector: 'my-app',
template: `
<form novalidate [formGroup]="form">
<div>
<select type="text" class="form-control" name="title" formControlName="title">
<option *ngFor="let title of titles" value="{{title}}">{{title}}</option>
</select>
</div>
<div>
<input type="text" class="form-control" name="name" formControlName="name">
</div>
<fieldset formGroupName="address">
<legend>Address</legend>
<input type="text" class="form-control" name="street" formControlName="street">
<input type="text" class="form-control" name="city" formControlName="city">
</fieldset>
</form>
`,
})
export class App implements OnInit {
private form: FormGroup;
private titles: string[] = ['Mr', 'Mrs', 'Ms'];
constructor(private fb: FormBuilder){
}
ngOnInit() {
this.form = this.fb.group({
title: 'Mr',
name: '',
address: this.fb.group({
street: '',
city: ''
})
});
this.form.get('name').valueChanges
.do(changes => {
console.log('name has changed:', changes)
})
.subscribe();
this.form.get('title').valueChanges.subscribe(
changes => console.log('title has changed:', changes)
);
this.form.get('address').valueChanges.subscribe(
changes => console.log('address has changed:', changes)
);
}
}
@NgModule({
imports: [ BrowserModule, FormsModule, ReactiveFormsModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
Une autre solution consisterait à utiliser l'événement "ngModelChange"
Modifiez cela dans votre modèle:
<input type="text" class="form-control" (ngModelChange)="doNameChange($event)" name="name" formControlName="name">
Dans votre composant, vous gérez alors votre événement de changement:
doNameChange(event: any){
alert("change")
}
un des moyens est:
debounceTime fera un abonnement après des millisecondes données. Si non requis, ignorer.
distinctUntilChanged forcera la souscription uniquement lors du changement de valeur réelle.
this.form.controls['form_control_name']
.valueChanges
.debounceTime(MilliSeconds)
.distinctUntilChanged()
.subscribe(val => {
});
J'avais aussi des problèmes avec ça.
Je voulais faire debounceTime dans mon cas, donc cela ne répondait pas à mes besoins.
J'ai en fait oublié de m'inscrire!
Mais j’ai pu obtenir des changements de valeur à activer de cette façon aussi:
this.form.get('name').valueChanges.forEach(
(value) => {console.log(value);} )
Provenant d'ici dans le Angular docs: hero-detail-component.ts