2016-11-30 2 views
0

Der KontextStrukturierung Angular2 Forms - Wie bedingte Formularfelder enthalten, die

Jecelyn Yeen ein excellent article, wie Validierung hat verschachtelte Formen in Angular2 zu organisieren.

In ihrem Beispiel verwendet sie ein Array, um mehrere Adressformular-Unterkomponenten anzuzeigen, so dass der Benutzer endlos auf "Adresse hinzufügen" klicken kann und das Formular wird weiterhin korrekt validiert. Ich möchte etwas Ähnliches machen, aber anstatt eine Reihe von Unterformularen zu haben, zeige stattdessen eine andere Unterform an, abhängig vom Wert eines Dropdown-Menüs.

Ich versuche, meinen Code ähnlich zu ihrem zu strukturieren, außer, anstatt ein Formular-Generator-Array zurückzugeben, verwende ich eine Formulargruppe für jedes Teilformular, das ich anzeigen möchte. Wenn eine Dropdown-Option ausgewählt ist, lösche ich die Formulargruppen, die nicht angezeigt werden sollen, und erzeuge die Formulargruppen neu, die nicht angezeigt werden sollen. Das Problem, das ich bekomme, ist, dass das übergeordnete Formular keine Änderungen innerhalb des untergeordneten Formulars aufgreift, wenn es auf diese Weise strukturiert wird.

Der Kodex

ts:

public showNameForm: boolean = false; 
public showAddressForm: boolean = false; 
public showPhoneNumberForm: boolean = false; 

constructor (fb: FormBuilder) { 
    this.myForm = fb.group({ 
    nameInfo: this.getNameForm(), 
    addressInfo: this.getAddressForm(), 
    phoneNumberInfo: this.getPhoneNumberForm() 
    }); 
} 

getNameForm() { 
    return this.fb.group({ 
    name: ["", Validators.required] 
    }); 
} 

getAddressForm() { 
    return this.fb.group({ 
    address1: ["", Validators.required], 
    address2: ["", Validators.required], 
    city: ["", Validators.required], 
    state: ["", Validators.required], 
    zipcode: ["", Validators.required] 
    }); 
} 

getPhoneNumberForm() { 
    return this.fb.group({ 
    phone: ["", Validators.required] 
    }); 
} 

handleDropdownSelect (value) { 
    if(value === 1) { 
    this.showNameForm = true; 

    this.myForm.controls['nameInfo'] = this.getNameForm(); 
    delete this.myForm.controls['addressInfo']; 
    delete this.myForm.controls['phoneNumberInfo']; 
    } 
    // Similar for other cases, e.g. if value is 2, only show addressInfo 
} 

html:

<form [formGroup]="myForm"> 
    <div [formGroupName]="'nameInfo'" *ngIf="showNameForm"> 
    <input type="text" formControlName="name" /> 
    </div> 
    <!-- Similar for other fields --> 
    <!-- ... --> 
    <button [ngClass]="{disabled: !myForm.valid}">Submit</button> 
</form> 

Dadurch wird die Submit-Button immer ungültig bleibt, auch nachdem ich all den gewünschten Text eingeben. Inspizieren Sie das Formular-Objekt mit dem Chrome-Debugger, ich sehe, dass myForm.value zu

{ 
    nameInfo: { 
    name: "" 
    } 
} 

Mit anderen Worten gleich ist, der Text, den ich geben in die Unterform Gruppen wird von der Mutterform nie abgeholt. Aber ich kann sehen, dass myForm.controls.nameInfo hat einen Wert mit den richtigen Informationen, und das Gleiche, wenn die anderen ausgewählt sind. Alle diese Eigenschaften besitzen eine valid Eigenschaft von true. Das übergeordnete Formular nimmt diese Änderungen jedoch nicht auf, wenn ich nicht manuell myForm.updateValueAndValidity() aufrufen. Dies ist nicht ideal, da ich möchte, dass das Formular als gültig angezeigt wird, sobald es gültig wird, ohne dass ich meinen eigenen Ereignis-Listener hinzufügen muss, um es zu ermöglichen.

+0

Warum Verbindest du '[ngClass]' anstelle des Attributs [[disabled] 'auf der Schaltfläche? Eine davon steuert tatsächlich, ob die Schaltfläche deaktiviert ist oder nicht. Der andere wendet eine CSS-Klasse auf die Schaltfläche an, basierend auf der Gültigkeit des Formulars. http://plnkr.co/edit/usLejtwhMZGjyxS6InCb?p=preview – silentsod

+0

Sie sind richtig! Ich entschuldige mich. Ich habe das lokal gesehen, weil ich aktualisiert habe, welches Formular angezeigt werden soll, wenn das Dropdown ausgewählt wurde. Ich löschte die anderen Formularkomponenten und machte dann 'myForm.addressInfo = this.getAddressForm()', was die Vorlage brach. Ich denke also, die wahre Frage ist, wie Subformulare selektiv angezeigt werden und das Elternformular korrekt validiert werden kann (es scheint, dass es als ungültig zurückkehrt, wenn die nicht angezeigten Formulare Felder erfordern, die leer sind. wird nicht angezeigt). –

+0

IIRC deaktivierte Steuerelemente zählen nicht zur Validierung.Programmatisch deaktivieren über 'disable()' auf der Gruppe, die Sie nicht anzeigen, sollten den Trick tun. Wenn Sie Ihre Frage aktualisieren möchten und wenn das funktioniert, werde ich zurückkommen und es als Antwort morgen setzen. – silentsod

Antwort

1

In den Kommentaren wurden Steuerelemente ausgeblendet, die immer noch zur Validierung zählen.

Wenn Sie sich versteckt, und wählen Sie FormGroups zeigen und wollen sie nicht auf die Validierung oder die form.value Eigenschaft zählen, dann können Sie disable() entweder auf den einzelnen Kontrollen oder auf der enthaltenden FormGroup nennen:

this.myForm.addressInfo.disable(); // disables the entire addressInfo group 
// which removes it from validation, thus preventing false flags. 
Verwandte Themen