2017-07-24 1 views
0

Ich habe eine einfache Komponente, die reaktive Formulare implementiert und 7 Eingabefelder eingerichtet, die select Eingänge sind.Angular2 Reactive Forms Validierung

Ich versuche, einen Validator darauf anzuwenden, um mindestens einen von ihnen zu zwingen, einen Wert zu enthalten.

Komponente:

renderForm() { 
     this.importForm = this.fb.group({ 
      costCenter: [], 
      area: [], 
      silo: [], 
      department: [], 
      location: [], 
      segment: [], 
      role: [] 
     }, 
      { 
       validator: (formGroup: FormGroup) => { 
        return this.validateFilter(formGroup); 
       } 
      }); 
    } 

    /** 
    * Checks to see that at least one of the filter 
    * options have been filled out prior to searching 
    * for employees. 
    * 
    * @param formGroup 
    */ 
    validateFilter(formgroup: FormGroup) { 
     if (formgroup.controls["costCenter"].value || 
      formgroup.controls["area"].value || 
      formgroup.controls["silo"].value || 
      formgroup.controls["department"].value || 
      formgroup.controls["location"].value || 
      formgroup.controls["segment"].value || 
      formgroup.controls["role"].value 
     ) { 
      return { validateFilter: true }; 
     } else { 
      return null; 
     } 
    } 

Als ich mein Formular ein inspizieren den form selbst, sie sagt immer wieder, dass seine Gültigkeit, auch wenn keiner der Eingänge ausgefüllt wurden.

Wenn ich mir die einzelnen Formularsteuerwerte anschaue, werden sie als null angezeigt und überprüft, dass kein Wert gespeichert wurde.

Alles bemerkbar, dass ich falsch mache?

Update:

wenn diese Angelegenheiten nicht sicher, aber ein Wert meiner Eingabe ist ein Array:

enter image description here

Ich würde denken, dass dies immer noch true anzusehen ist, wenn sie die Prüfung sehen, ob es einen Wert hat?

Update 2: Hier ist ein Ausschnitt meines HTML. Dieser Ausschnitt ist für jedes Dropdown identisch und bezieht sich nur auf eine andere Funktion zum Auffüllen.

<tr> 
       <td class="col-md-2 strong">Area</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="area" [allowClear]="true" [multiple]="true" [items]="getAreas()" placeholder="Select one or more Areas"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 

Update 3:

Wie gewünscht, hier ist die vollständige HTML-Vorlage.

<tbody> 
      <tr> 
       <td class="col-md-2 strong">Cost Center</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="costCenter" [allowClear]="true" [multiple]="true" [items]="getCostCenters()" placeholder="Select one or more Cost Centers"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Area</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="area" name="area" [allowClear]="true" [multiple]="true" [items]="getAreas()" placeholder="Select one or more Areas"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Silo</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="silo" name="silo" [allowClear]="true" [multiple]="true" [items]="getSilos()" placeholder="Select one or more Silos"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Department</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="department" name="department" [allowClear]="true" [multiple]="true" [items]="getDepartments()" placeholder="Select one or more Departments"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Location</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="location" name="location" [allowClear]="true" [multiple]="true" [items]="getLocations()" placeholder="Select one or more Locations"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Segment</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="segment" name="segment" [allowClear]="true" [multiple]="true" [items]="getSegments()" placeholder="Select one or more Segments"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Role</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="role" name="role" [allowClear]="true" [multiple]="true" [items]="getRoles()" placeholder="Select one or more Roles"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
     </tbody> 

Update 4:

Als Test kommentierte ich alle von der Validierungslogik und gerade return { validFilter: true }; erwartet, dass es meiner Form valid, dass seine erzählen. Dies war jedoch nicht der Fall und das Formular ist immer noch invalid.

Scheint so, als könnte es irgendwo anders ein Problem geben?

+0

Dies ist ungültig, da Abteilung, Standort und usw. null sind. Können Sie Ihre Vorlage zeigen? – brijmcq

+0

@brijmcq Ich habe der Frage ein HTML-Snippet hinzugefügt. – SBB

+0

@brijmcq - Ich habe jedem Element die Eigenschaft 'name =' hinzugefügt, was zu demselben Problem führt. – SBB

Antwort

1

Also ich könnte falsch sein, aber auf dem ersten Blick sieht es aus wie Sie den Validator haben gemischt. Es sollte die folgende sein:

/** 
* Checks to see that at least one of the filter 
* options have been filled out prior to searching 
* for employees. 
* 
* @param formGroup 
*/ 
validateFilter(formgroup: FormGroup) { 
    if (formgroup.controls["costCenter"].value || 
     formgroup.controls["area"].value || 
     formgroup.controls["silo"].value || 
     formgroup.controls["department"].value || 
     formgroup.controls["location"].value || 
     formgroup.controls["segment"].value || 
     formgroup.controls["role"].value 
    ) { 
     return null 
    } else { 
     return { noFilterOptionsSet: true }; 
    } 
} 

Die Art und Weise Validierer Arbeit ist, dass ein „gültig“ Validator null zurückgibt, mit anderen Worten: „Ich kann nichts falsch gefunden haben“. Wenn es etwas findet, gibt es ein Objekt mit einer deskriptiv benannten Eigenschaft mit einem booleschen Wert zurück, der den Zustand der Eigenschaft weiter beschreibt, höchstwahrscheinlich "wahr". Dies wird verwendet, um verschiedene Fehler auszulösen und die Form des aufgetretenen Fehlers zu informieren, so dass Sie verschiedene Beschriftungen und Fehlermeldungen anwenden können.

+0

Ich denke das ist es! Ein Schnelltest hat gezeigt, dass er die Validierung bestanden hat, als ich einen Wert für eine einzelne Eingabe ausgewählt habe. Wenn ich den Wert jedoch entfernte, sah mein Formular wie ein leeres Array statt null aus. 'role: Array (0)' vs als es begann als 'role: null'. Ich muss nur herausfinden, ob ich diese beim Entfernen auf null zurücksetzen kann, und dann sollte die Validierung beim Entfernen auf ungültig zurückgesetzt werden. Wird diese Antwort hier in Kürze akzeptieren. – SBB

+0

Möglicherweise müssen Sie einen "Löschen" -Knopf haben, der die 'setValue'-Methode für die Steuerelemente verwendet, um sie in einen" Null "-Zustand zurückzuversetzen. – joshrathke

+0

Ich habe es funktioniert. Ich setze meine Formularsteuerelemente einfach auf ein leeres Feld 'costCenter: [[]]' und dann in meinem Validator 'formgroup.controls ["costCenter"]. Value.length'. Schöne Arbeit auf das fangen :) – SBB

1

können Sie versuchen, diese

this.importForm = this.fb.group({ 
      costCenter: ['', [Validators.required], 
      area: ['', [Validators.required], 
      silo: ['', [Validators.required], 
      department: ['', [Validators.required], 
      location: ['', [Validators.required], 
      segment: ['', [Validators.required], 
      role: ['', [Validators.required] 
     }); 

Dies würde Ihre Form mit Standardwerten von ‚‘ mit den erforderlichen Validierungs machen. Der Grund, warum die Validatoren in Array ist, weil Sie auch mehrere Validierer wie dieses

department: ['', [Validators.required, Validators.minLength(3)]], 

hoffe, das hilft

+0

Ich habe dies versucht und jetzt, auch wenn ich einen Wert für eine der Eingaben auswählen, ist das Formular "ungültig". Als Test habe ich sogar versucht, einen Wert für alle Eingaben zu wählen, und das hat keinen Unterschied gemacht. – SBB

0

Mein Code sieht etwas anders hinzufügen ...nicht sicher, ob es Dinge für Sie ändern würde:

validateFilter(formgroup: FormGroup) { 
    if (formgroup.get("costCenter").value || 
     formgroup.get("area").value || 
     formgroup.get("silo").value || 
     formgroup.get("department").value || 
     formgroup.get("location").value || 
     formgroup.get("segment").value || 
     formgroup.get("role").value 
    ) { 
     return { 'validateFilter': true }; 
    } else { 
     return null; 
    } 
} 
  • In der return-Anweisung, ist der Rückgabewert ein String und ein boolean, so dass ich eingeschlossen es in Anführungszeichen.

  • Ich habe auch .get anstelle von .controls verwendet, aber das sollte nicht wichtig sein.

Ich habe ein Arbeitsbeispiel einer Validator benutzerdefinierte Gruppe hier als Referenz, wenn das hilft: https://github.com/DeborahK/Angular2-ReactiveForms/tree/master/Demo-Final-Updated

+0

Ich habe dies versucht und stieß auf das gleiche Problem. Das ganze Formular ist ungültig, auch wenn ich eine Eingabe auswähle. Ich habe meine ursprüngliche Frage aktualisiert, um sicherzustellen, dass es kein Problem mit meinem Wert als Array gibt. Würde dies immer noch als "wahr" getestet? Ich verwende ein Plugin "ng-select", das mir erlaubt, mehrere Werte aus dem Dropdown auszuwählen, so dass die endgültige Ausgabe ein Array ist. – SBB

+0

so klingt es wie jedes Eingabeelement dann * hat * einen Wert, der das Array ist. Haben Sie versucht, die Array-Länge zu überprüfen, anstatt nach Null zu suchen? 'formgroup.get (" costCenter "). value.length' – DeborahK

+0

Guter Aufruf, ich habe versucht, die '.length'-Prüfung dort hinzuzufügen, aber es ergibt sich dasselbe ungültige Formular. – SBB

Verwandte Themen