wake-up-neo.com

Richtige Abonnement für valueChanges in Angular 2

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?

6
user776686

Ihr Plunker funktionierte:

  1. fügen Sie diese Importanweisung in app.ts hinzu
  import 'rxjs/add/operator/do';
  1. Entfernen Sie das Semikolon nach der Anweisung .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")
}
2
Karl

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

0
JGFMK