2017-07-24 99 views
0

我有一個簡單的組件,它實現反應形式並設置7個輸入字段,它們是select輸入。Angular2反應形式驗證

我想申請一個驗證它迫使他們中的至少一個包含一個值。

組件:

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; 
     } 
    } 

當我提交我的形式的檢查form本身,它口口聲聲說其有效的,即使沒有任何的輸入已經被填寫。

當我看個人的形式控制值,它們被顯示爲null,驗證沒有值已存儲。

任何明顯的我做錯了?

更新:

不知道這事,但我輸入的值是一個數組:

enter image description here

我會認爲這仍然被認爲是true測試時看看它是否有價值?

更新2: 這是我的HTML代碼片段。這段代碼對於每個下拉菜單都是相同的,只是引用不同的函數來填充它。

<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> 

更新3:

按照要求,這裏是完整的HTML模板。

<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> 

更新4:

作爲一個測試,我評論了所有的驗證邏輯的和剛剛返回return { validFilter: true };期待它告訴我的形式,它的valid。但是,情況並非如此,表格仍爲invalid

似乎在其他地方可能存在潛在的問題?

+0

這將是無效的,因爲部門,地點等是空的。你能展示你的模板嗎? – brijmcq

+0

@brijmcq我在問題中添加了一個HTML代碼片段。 – SBB

+0

@brijmcq - 我將'name ='屬性添加到每個元素,導致相同的問題。 – SBB

回答

1

所以我可能是錯的,但第一眼看上去你有驗證混合起來。它應該是以下幾點:

/** 
* 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 }; 
    } 
} 

的方式驗證器的工作是一個「有效」驗證返回NULL,換句話說:「我沒有發現任何錯誤。」如果它發現它返回一個具有描述性命名屬性的對象,其布爾值進一步描述該屬性的狀態,最有可能是「真」。這用於觸發不同的錯誤並通知發生錯誤的形式,以便您可以應用不同的標籤和錯誤消息。

+0

我認爲這就是它!快速測試表明,當我爲單個輸入選擇一個值時,它通過了驗證。但是,當我刪除該值時,看起來像我的表單將該值保留爲空數組而不是null。 'role:Array(0)'vs當它作爲'role:null'開始時。我只需要查看是否可以在刪除時將其重置爲空,然後在刪除後驗證應重置爲無效。很快就會接受這個答案。 – SBB

+0

您可能需要有一個「清除」按鈕,使用控件上的setValue方法將它們返回到null狀態。 – joshrathke

+0

我懂了。我只是將我的表單控件設置爲一個空數組'costCenter:[[]]',然後在我的驗證器中,我做了'formgroup.controls [「costCenter」] .value.length'。 不錯的工作捕捉:) – SBB

1

你可以試試這個

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] 
     }); 

這將使您的形式與'與需要驗證默認值。爲什麼驗證是在陣列的原因是因爲你還可以添加多個驗證這樣

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

希望這有助於

+0

我給了這個嘗試,現在即使當我爲任何輸入選擇一個值時,表單也是「無效的」。作爲一項測試,我甚至試圖爲所有輸入選擇一個值,並沒有什麼不同。 – SBB

0

我的代碼看起來有點不同...不知道這是否會改變你的東西:

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; 
    } 
} 
  • 在return語句,返回值是一個字符串和一個布爾值,所以我封閉它引號。

  • 我也使用.get而不是.controls,但這應該不重要。

我有一個自定義組驗證的工作示例這裏引用是否有幫助:https://github.com/DeborahK/Angular2-ReactiveForms/tree/master/Demo-Final-Updated

+0

我試了一下,遇到了同樣的問題。即使在我選擇輸入時,整個表單也是無效的。我更新了我原來的問題,以確保我的值是一個數組沒有問題。這仍然會測試爲'真?'我正在使用插件'ng-select',它允許我從下拉列表中選擇多個值,因此最終輸出是一個數組。 – SBB

+0

所以它聽起來像每個輸入元素,然後*有一個值是數組。你有沒有嘗試過檢查數組長度,而不是檢查null? 'formgroup.get(「costCenter」).value.length' – DeborahK

+0

好的調用,我嘗試在那裏添加'.length'檢查,但是,它導致了同樣的無效格式。 – SBB