Angular 2:向ngModelGroup添加验证器

时间:2016-11-15 14:33:51

标签: javascript validation angular angular2-forms

我正在使用ngModelGroup指令将多个表单输入组合在一起。

在文档(https://angular.io/docs/ts/latest/api/forms/index/NgModelGroup-directive.html)中,我读到有validators: any[]属性。

这是否意味着我可以添加自定义验证程序功能,仅验证ngModelGroup?如果是这样,我该如何使用它?

这很棒,因为我想检查ngModelGroup中是否至少有一个复选框已经过检查。我无法使用required,因为这意味着需要所有复选框。我在文档中找不到任何相关内容,或者我找错了地方?

3 个答案:

答案 0 :(得分:8)

这完全可以使用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>

这里有一个可以玩的所有玩具: http://plnkr.co/edit/AXWGn5XwRo60fkqGBU3V?p=preview

答案 1 :(得分: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>
...

这会验证允许我显示错误并禁用提交按钮的表单。

谢谢大家的帮助!

答案 2 :(得分:-1)

看起来ModelGroup中的每个控件都应该有自己的验证器。完成此操作后,您可以通过验证器数组访问每个。所以将所需的属性添加到所需的输入