2016-11-15 87 views
1

我正在使用ngModelGroup指令將多個表單輸入組合在一起。Angular 2:將驗證器添加到ngModelGroup

在文檔中(https://angular.io/docs/ts/latest/api/forms/index/NgModelGroup-directive.html)我看到有一個validators: any[]屬性。

這是否意味着我可以添加一個自定義驗證器函數,該函數僅驗證ngModelGroup?如果是這樣,我該如何使用它?

這會很棒,因爲我想檢查是否至少有一個ngModelGroup中的複選框被選中。我不能使用required,因爲那意味着全部複選框是必需的。我在文檔中找不到任何關於此的內容,或者我在錯誤的地方看到了什麼?

回答

4

這完全可能與ngModelGroup和用於驗證的自定義指令。理解這種工作原理的關鍵是:ngModelGroup

創建FormGroup實例並將其綁定到DOM元素。

首先,我們要建立我們的指令,它與什麼特別漂亮的樣板事情:

@Directive({ 
    selector: '[hasRequiredCheckboxInGroup]', 
    providers: [{provide: NG_VALIDATORS, useExisting: HasRequiredCheckBoxInGroup, multi: true}] 
}) 
export class HasRequiredCheckBoxInGroup implements Validator, OnChanges { 
    private valFn = Validators.nullValidator; 

    constructor() { 
    this.valFn = validateRequiredCheckboxInGroup(); 
    } 

    validate(control: AbstractControl): {[key: string]: any} { 
    return this.valFn(control); 
    } 
} 

我們的驗證功能,我們把我們的關鍵知識ngModelGroup創建FormGroup並應用:

function validateRequiredCheckboxInGroup() : ValidatorFn { 
     return (group) => { //take the group we declare in the template as a parameter 
     let isValid = false; //default to invalid for this case 
     if(group) { 
      for(let ctrl in group.controls) { 
      if(group.controls[ctrl].value && typeof group.controls[ctrl].value === 'boolean') { // including a radio button set might blow this up, but hey, let's be careful with the directives 
       isValid = group.controls[ctrl].value; 
      } 
      } 
     } 

     if(isValid) { 
      return null; 
     } else { 
      return { checkboxRequired: true }; 
     } 
     } 
    } 

最後,已經包含在我們的模塊的指令聲明,我們返回到模板(需要在一種形式):

<form #f="ngForm"> 
     <div ngModelGroup="checkboxes" #chks="ngModelGroup" hasRequiredCheckboxInGroup> 
      <input type="checkbox" name="chk1" [(ngModel)]="checks['1']"/> 
      <input type="checkbox" name="chk2" [(ngModel)]="checks['2']"/> 
     </div> 
     <div> 
     {{chks.valid}} 
     </div> 
</form> 

而這裏的這一切可用plunker一起玩: http://plnkr.co/edit/AXWGn5XwRo60fkqGBU3V?p=preview

+0

我們如何將參數傳遞給validate函數?例如,如果我想要一個自定義驗證器來強制數字輸入的最小/最大值? – Learning2Code

+0

正是我在找的!很好的例子謝謝 –

-1

看起來像ModelGroup中的每個控件都應該有自己的驗證器。一旦完成,你可以通過驗證器數組訪問每一個。所以將所需的屬性添加到所需的輸入

+0

就是這樣,並不是所有*複選框都是必需的。我只想檢查是否至少有一個檢查。如前所述,我目前在提交處理程序中執行該操作,但如果直到至少選中一個複選框,表單根本無法驗證,則會更好。 – Johan

0

感謝所有幫助我!我接受了Silentsod的回答,因爲它是最有幫助的。

我最終的解決方案只是使用FormBuilder來構建表單。

在我的組件,創建表單並添加驗證功能吧:

ngOnInit(): void { 
    // Validator function: 
    let validateMemberList = (group: FormGroup) => { 
     let checked = Object.keys(group.controls).reduce((count, key: string) => { 
      return count + (group.controls[key].value ? 1 : 0); 
     }, 0); 

     return checked === 0 ? {'minchecked': 1} : null; 
    }; 

    this.jobForm = this.formBuilder.group({ 
     jobTitle: ['', Validators.required], 
     // more inputs... 
     members: this.formBuilder.group({}, { 
      // The 2nd argument is an object with a validator property: 
      validator: validateMemberList 
     }), 
     supportMembers: this.formBuilder.group({}, { 
      validator: validateMemberList 
     }) 
    }); 

然後在我的模板:

<form [formGroup]="jobForm"> 
    <ul formGroupName="members"> 
     <li *ngFor="let user of teamMembers.members"> 
      <label class="e-label"> 
       <input class="e-input" type="checkbox" [formControlName]="user.$key"> 
       <user-badge [user]="user"></user-badge> 
      </label> 
     </li> 
    </ul> 
... 

這驗證表單讓我顯示錯誤並禁用提交按鈕。

謝謝大家的幫助!

相關問題