2016-11-07 2 views
9

Mit der Verwendung von Angular 2 ist die Zwei-Wege-Bindung in schablonenbasierten Formen einfach - Sie verwenden einfach die Bananen-Box-Syntax. Wie würden Sie dieses Verhalten in einer modellgesteuerten Form replizieren?Zweiwege-Bindung in reaktiven Formen

Zum Beispiel ist hier eine reaktive Standardform. Nehmen wir an, es ist viel komplizierter als es aussieht, mit vielen verschiedenen Eingaben und Geschäftslogik und daher für einen modellgesteuerten Ansatz geeigneter als ein vorlagengesteuerter Ansatz.

export class ExampleModel { 
    public name: string; 
    // ... lots of other inputs 
} 

@Component({ 
    template: ` 
     <form [formGroup]="form"> 
      <input type="text" formControlName="name"> 
      ... lots of other inputs 
     </form> 

     <h4>Example values: {{example | json}}</h4> 
    ` 
}) 
export class ExampleComponent { 
    public form: FormGroup; 
    public example: ExampleModel = new ExampleModel(); 

    constructor(private _fb: FormBuilder) { 
     this.form = this._fb.group({ 
      name: [ this.example.name, Validators.required ] 
      // lots of other inputs 
     }); 
    } 

    this.form.valueChanges.subscribe({ 
     form => { 
      console.info('form values', form); 
     } 
    }); 
} 

Im subscribe() kann ich alle Arten von Logik auf die Form Werte gelten und bei Bedarf abbilden. Ich möchte jedoch nicht jeden Eingabewert aus dem Formular abbilden. Ich möchte nur die Werte für das gesamte employee Modell sehen, wie es aktualisiert, in einem Ansatz ähnlich wie [(ngModel)]="example.name", und wie in der JSON-Pipe in der Vorlage angezeigt. Wie kann ich das erreichen?

Antwort

23

Sie können [(ngModel)] mit reaktiven Formen verwenden.

<form [formGroup]="form"> 
    <input name="first" formControlName="first" [(ngModel)]="example.first"/> 
    <input name="last" formControlName="last" [(ngModel)]="example.last"/> 
</form> 

export class App { 
    form: FormGroup; 
    example = { first: '', last: '' }; 

    constructor(builder: FormBuilder) { 
    this.form = builder.group({ 
     first: '', 
     last: '' 
    }) 
    } 
} 

Plunker

Das wird eine ganz andere Richtlinie als die, die ohne die formControlName verwendet würde. Bei reaktiven Formen wird es die FormControlNameDirective sein. Ohne die formControlName würde die NgModel Direktive verwendet werden.

+4

fragte eine ähnliche Frage in Angular/Angular und zwei der Kern-Entwickler sagte mir, dass Mischen von ngModel und reaktive Formen ist eine schlechte Idee. Sie sollten in der Lage sein, die Werte mit {{this.form.get ('first'). Value}} – Zuriel

+0

@Zuriel zu erhalten, aber wie kann ich meine lokalen modeldata direkt auf mein Formular ablegen, so habe ich zwei-Wege-Datenbindung für meine modeldata ? Denn ohne die obige Lösung muss ich meine formdata zurück zu meinem modeldata – squadwuschel

+4

https://angular.io/guide/reactive-forms zuordnen In Übereinstimmung mit dem reaktiven Paradigma bewahrt die Komponente die Unveränderlichkeit des Datenmodells und behandelt es als eine reine Quelle originaler Werte. Anstatt das Datenmodell direkt zu aktualisieren, extrahiert die Komponente Benutzeränderungen und leitet sie an eine externe Komponente oder einen externen Service weiter, der mit ihnen etwas tut (z. B. speichert) und ein neues Datenmodell an die Komponente zurückgibt, das den aktualisierten Modellzustand widerspiegelt. – Zuriel

1

Manchmal müssen Sie möglicherweise [(ngModel)] mit reaktiven Formen kombinieren. Ich könnte ein Eingabesteuerelement sein, das Sie nicht als Teil des Formulars benötigen, aber Sie müssen es trotzdem an den Controller binden. Dann können Sie verwenden: [(ngModel)]="something" [ngModelOptions]="{standalone: true}"

Verwandte Themen