Ich habe mit reaktiven Formularen und valueChanges
Subscription in Angular 2 herumgespielt. Ich verstehe nicht, warum bestimmte Subskriptionsformen nicht erlaubt sind.
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)
);
Dieser Plunker reproduziert das Problem (öffnen Sie die DevTools-Konsole, um den Fehler anzuzeigen):
ZoneAwareError {stack: "Fehler: Nicht erfasst (im Versprechen): TypeError: Kann nicht se…g.com/[email protected]/dist/zone.js: 349: 25) []", Nachricht: "Uncaught (in promise): TypeError: Proper kann nicht gesetzt werden… ore.umd.js: 8486: 93) ↵ at Array.forEach (native) ", originalStack:" Fehler: Nicht erfasst (in Promise): TypeError: Kann nicht… ps: // unpkg .com/zone.js @ 0.7.5/dist/zone.js: 349: 25) ", zoneAwareStack:" Fehler: Nicht erfasst (Versprechen): TypeError: Kann nicht se…g.com/[email protected] /dist/zone.js:349:25) [] ", Name:" Error "…}
Ist das erste Muster (mit do
) in der Tat nicht illegal?
Ihr Plunker funktionierte:
import 'rxjs/add/operator/do';
.do (changes => { console.log ('Name wurde geändert:', Änderungen) })
Veränderte geänderte App.ts
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 {}
Ein anderer Lösungsansatz wäre die Verwendung des Ereignisses "ngModelChange"
Ändern Sie dies in Ihrer Vorlage:
<input type="text" class="form-control" (ngModelChange)="doNameChange($event)" name="name" formControlName="name">
In Ihrer Komponente behandeln Sie dann Ihr Änderungsereignis:
doNameChange(event: any){
alert("change")
}
einer der Wege ist:
debounceTime Abonnement nach angegebenen Millisekunden. Wenn nicht erforderlich, ignorieren.
distinctUntilChanged erzwingt die Subskription nur bei einer tatsächlichen Wertänderung.
this.form.controls['form_control_name']
.valueChanges
.debounceTime(MilliSeconds)
.distinctUntilChanged()
.subscribe(val => {
});
Ich hatte auch Probleme damit.
Ich wollte in meinem Fall debounceTime machen, sodass meine Bedürfnisse dadurch nicht gelöst wurden.
Ich habe eigentlich vergessen zu abonnieren!
Aber ich konnte auch Wertänderungen erhalten, um diesen Weg zu aktivieren:
this.form.get('name').valueChanges.forEach(
(value) => {console.log(value);} )
Von hier aus in den Angular -Dokumenten bezogen: hero-detail-component.ts