2017-01-17 9 views
2

mit Könnte mir bitte jemand erklären, warum bei dem Versuch, ein Optionsfeld zu validieren, ohne NgFor für die Optionen funktioniert:Radiobutton Validierungsvorlage angetrieben Formen und NgFor in Angular 2

@Component({ 
    selector: 'rio-app', 
    template: ` 
    <form #myForm="ngForm"> 

     <label> 
     Male: 
     <input type="radio" name="gender" value="Male" 
      ngModel required #gender="ngModel" 
     /> 
     </label> 

     <label> 
     Female: 
     <input type="radio" name="gender" value="Female" 
      ngModel required #gender="ngModel" 
     /> 
     </label> 

     <div [hidden]="!gender.hasError('required')"> 
     The gender is required 
     </div> 

    </form> 
    ` 
}) 
export class AppComponent {} 

Plunker

Aber wenn ich versuche, das gleiche zu tun NgFor mit ihm versagt:

@Component({ 
    selector: 'rio-app', 
    template: ` 
    <form #myForm="ngForm"> 

     <label *ngFor="let gender of genders"> 
     {{ gender }}: 
     <input type="radio" name="gender" [value]="gender" 
      ngModel required #myGender="ngModel" 
     /> 
     </label> 

     <div [hidden]="!myGender.hasError('required')"> 
     The gender is required 
     </div> 

    </form> 
    ` 
}) 
export class AppComponent { 
    genders = ['Male', 'Female'] 
} 

Plunker

Ich erhalte eine Fehlermeldung in der Konsole des Browsers, der sagt:

Cannot read property 'hasError' of undefined

Irgendwelche Ideen?

Antwort

2

So landete ich eine issue im Angular Repo-Öffnung und eine Person (@alexzuza) gab mir eine gute Antwort, die ich für zukünftige Referenzen mit Ihnen teilen möchten:

import { Component } from '@angular/core'; 

@Component({ 
    selector: 'rio-app', 
    template: ` 
    <form #myForm="ngForm"> 

     <input type="text" /> 

     <ng-container *ngFor="let gender of genders; let isLast = last"> 

     <label> 
      {{ gender }}: 
      <input type="radio" name="gender" [value]="gender" 
      ngModel required #myGender="ngModel" 
      /> 
     </label> 

     <div *ngIf="isLast" [hidden]="!myGender.hasError('required')"> 
      The gender is required 
     </div> 

     </ng-container> 

    </form> 
    ` 
}) 
export class AppComponent { 
    genders = ['Male', 'Female'] 
} 

Zu meinem Verständnis, die Trick ist alles innerhalb der NgFor unter Verwendung der <ng-container> zu tun, weil jede Variable innerhalb der Schleife erstellt wird Block Umfang haben.

Hier ist ein Arbeits plunker

1

Ich habe keine Ahnung, warum 'myGender' undefined ist und ich habe keine Idee, wie man dieses Problem mit dem normalen FormsModule lösen kann, um ganz ehrlich zu Ihnen zu sein, ich weiß, wie Sie das mit dem 'ReactiveFormsModule' lösen können.

In Ihrem AppModule müssen Sie den Import von

Forms Modul ändern
import { FormsModule } from '@angular/forms'; 

zu

import { ReactiveFormsModule } from '@angular/forms'; 

Und die Einfuhr ändern in Ihrem @NgModule

@NgModule({ 
    imports: [ BrowserModule, FormsModule ], 
    declarations: [ AppComponent ], 
    bootstrap: [ AppComponent ] 
}) 

Sie haben werden um jetzt einige neue Dinge in Ihre Komponente zu importieren

import { FormGroup, FormBuilder, Validators } from '@angular/forms'; 

Und Sie werden Ihre Form ein wenig für die ReactiveFormsModule

<label *ngFor="let gender of genders"> 
    {{ gender }}: 
    <input type="radio" name="gender" [value]="gender" 
     required [formControl]="myForm.controls['gender']" 
    /> 
    </label> 

    <div [hidden]="!myForm.controls['gender'].hasError('required')"> 
    The gender is required 
    </div> 

</form> 

Jetzt können Sie die Formular-Builder verwenden, ändern müssen, um Ihre Formular-Steuerelemente zu definieren und Validierer

export class AppComponent { 
    genders = ['Male', 'Female']; 
    myForm : FormGroup; 

    constructor(private formBuilder: FormBuilder){ 
    this.myForm = this.formBuilder.group({ 
     'gender' : [null, Validators.required] 
    }); 
    } 
} 

Dies ist die einzige Möglichkeit, um dieses Problem zu umgehen, wenn Sie wirklich eine for-Schleife verwenden möchten.

Edit:

Plnkr example

+0

Vielen Dank für Ihre ausführliche Antwort. Leider kann ich den FormBuilder in diesem Fall nicht verwenden, da ich diesen Codeabschnitt verwende, um die Prinzipien von Template-gesteuerten Formularen mit Validierung zu lehren. –

2

an diesen zweiten Plunker Blick scheint es, dass die Schablone Referenzvariable #myGender innerhalb der *ngFor definiert ist nicht sichtbar außerhalb d.h. in dieser Fehlermeldung div.

Aber Sie haben Zugriff auf diese Ebene zu #myForm obwohl, damit Sie auf Fehler auf das Geschlecht FormControl überprüfen können.

<div [hidden]="!myForm.controls.gender?.hasError('required')"> 
    The gender is required 
</div> 

aus dem Winkel doco wusste ich, dass die geschlechtsspezifische Variable in der *ngFor Definition definierte nicht sichtbar sein würde, aber ich war über Template-Variablen innerhalb dieses Blockes nicht sicher.Ein anderer könnte uns eine bessere Erklärung liefern.

+0

Vielen Dank für die Problemumgehung, ich könnte sie jetzt verwenden, aber dies könnte ein Angular Bug sein . Ich könnte ein Problem in ihrem Repo öffnen –

+0

Vielen Dank! – SajithNair