首页 > 解决方案 > 如何仅在使用 FormGroup 选择其中之一时才需要复选框

问题描述

FormGroup我在 Angular 4 中使用和进行自定义验证有一些问题FormControl。我有一个带有多个复选框的页面,在这个例子中是 6 个。其中三个是一直需要的,另外三个操作系统只有在选择其中一两个时才需要。如果没有选择它们,您可以通过验证。

我在 ngOnInit 方法中初始化我的 FormGroup,它看起来像这样

ngOnInit() {

    let statements = new FormGroup({});

    for (let i = 0; i < this.characters.length; i++) {
      const element = this.characters[i];
      statements.addControl(element.surname, new FormControl(false, CustomValidator.required));
    }

    statements.addControl(this.firstPerson.surname, new FormControl(false, CustomValidator.requiredPredicate(
       //here I have problem to write predicate which check if thirdPerson or secondPerson checbox was selected
    ));
    statements.addControl(this.secondPerson.surname, new FormControl(false, CustomValidator.requiredPredicate(
       //here I have problem to write predicate which check if firstPerson or third checbox was selected
    ));
    statements.addControl(this.thirdPerson.surname, new FormControl(false, CustomValidator.requiredPredicate(
      //here I have problem to write predicate which check if firstPerson or secondPerson checbox was selected
    ));

    this.fullData = new FormGroup({
      //here I have more than statemets, thats why I have fullData
      statements: statements
    });
  }

这里的 for 循环用于填充所有需要的 checbkox。但我认为我不能为最后三个做这件事,我需要检查是否选择了其他两个。在谓词内部我不知道,如何检查是否选择了其他两个 FormControls(checkboxes)。

这个组件的视图看起来像这样

<form [formGroup]="fullData">
  <div formGroupName="statements">
    <p>All of these 3 are required</p>
    <div *ngFor="let character of characters">
      <custom-checkbox
      [controlName]="character.surname"
      [formGroup]="fullData.get('statements')"
      [id]="character.name"
      [label]="character.name + ' ' + character.surname">
    </custom-checkbox>
    </div>

    <br />
    <br />
    <p>Only required when one of them is clicked</p>
    <custom-checkbox
      [controlName]="firstPerson.surname"
      [formGroup]="fullData.get('statements')"
      [id]="firstPerson.name"
      [label]="firstPerson.name + ' ' + firstPerson.surname">
    </custom-checkbox>

    <custom-checkbox
      [controlName]="secondPerson.surname"
      [formGroup]="fullData.get('statements')"
      [id]="secondPerson.name"
      [label]="secondPerson.name + ' ' + secondPerson.surname">
    </custom-checkbox>

    <custom-checkbox
      [controlName]="thirdPerson.surname"
      [formGroup]="fullData.get('statements')"
      [id]="thirdPerson.name"
      [label]="thirdPerson.name + ' ' + thirdPerson.surname">
    </custom-checkbox>
    <button type="button" (click)="onSubmit(fullData)"> Submit </button>
  </div>
</form>

我在这里使用自定义 checbkox,因为我想在更多地方使用它并扩展它。CustomValidation 类是这样的。

export interface ValidationError {
  [msg:string] : boolean;
}


export class CustomValidator {

  static required(control: any): ValidationError {
      if(control.value && (control.value.length === undefined || control.value.length >0)) {
        return null;
      }

      return {"VALIDATION.REQUIRED": false};
  }

  static requiredPredicate(predicate: any): ValidatorFn {
    return function(control: any){
      const value = predicate();
      if(value){
        return CustomValidator.required(control);
      }

      return null;
    }
  }
}

知道我该怎么做吗?

CustomChecbkox 代码:

export class CustomCheckboxComponent implements OnInit, OnDestroy {

  @Input('label') label: string;óó
  @Input('controlName') controlName: string;
  @Input('formGroup') formGroup: FormGroup;
  @Input('id') id: string;

  @ViewChild('inputField') inputField: any;
  @ViewChild('surroundingDiv') surroundingDiv: any;

  isValid: boolean = true;
  fieldUpdated: boolean = false;
  shouldDisplayError: boolean = false;
  displayError: boolean = false;

  constructor(public cd: ChangeDetectorRef) {
  }

  ngOnDestroy(): void {
  }

  fieldChanged(value) {
    if (!this.fieldUpdated) {
      this.fieldUpdated = true;
      this.validateField(value);
    }
  }

  validateField(value): boolean {
    if (!this.fieldUpdated) {
      return true;
    }
    this.isValid = this.formGroup.get(this.controlName).errors ? false : true;
    if ((this.fieldUpdated) && !this.shouldDisplayError) {
      this.shouldDisplayError = true;
    }

    this.displayError = !this.isValid && this.shouldDisplayError;
    return !this.displayError;
  }

  ngOnInit() {
  }


}

和 html

<div  class="custom-checkbox"
        [formGroup]="formGroup"
      #surroundingDiv
      [ngClass]="{'custom_validation' : displayError}">
    <label class="mdl-checkbox mdl-checkbox--pink mdl-js-checkbox mdl-js-ripple-effect"
           for="{{id}}">
        <input class="mdl-checkbox__input"
               type="checkbox"
               id="{{id}}"
               formControlName="{{controlName}}"
               (change)="fieldChanged($event.target.value)"
               #inputField
        >{{ label }}
    </label>
    <div class="custom-validation__error" *ngIf="displayError" style="padding-left: 24px;">
        <span *ngFor="let error of formGroup.get(controlName).errors "
        >{{error}}</span>
    </div>
</div>

标签: angularangular4-forms

解决方案


推荐阅读