带有参数的自定义验证器不适用于 angular

问题描述

在我的响应式表单中,我有一个文本框和一个复选框。我希望在选中复选框时,文本框可以为 null 或为空。如果未选中复选框,则应显示所需值的验证消息。所以我写了一个带参数的自定义验证器。但是验证器不起作用表单代码如下:

<form [formGroup]="frmExpenseHead">
  <div class="form-group row">
    <label for="Code" class="col-sm-12 col-form-label">Code</label>
    <div class="col-sm-10">
      <input type="text" class="form-control" [(ngModel)]="txtCode" id="code" name="code" formControlName="code"
        [ngClass]="{ 'is-invalid': submitted && f.code.errors }">
      <div *ngIf="submitted && f.code.errors" class="invalid-Feedback">
        <div *ngIf="f.code.errors.conditionrequired">Code is required</div>
      </div>
    </div>

    <div class="col-sm-2 form-check">
      <input class="form-check-input" type="checkBox" [(ngModel)]="chkAutoCode" id="autoCode" name="autoCode"
        formControlName="autoCode">
      <label class="form-check-label" for="autoCode">
        Auto Generate
      </label>
    </div>
  </div>

  <div class="text-center">
    <button class="btn btn-primary mr-1" (click)="onSubmit()">Register</button>
    <button class="btn btn-secondary" type="reset" (click)="onReset()">Cancel</button>
  </div>
</form>

ts文件代码为:

@Component({
  selector: 'app-expense-head',templateUrl: './expense-head.component.html',styleUrls: ['./expense-head.component.css']
})
export class ExpenseHeadComponent implements OnInit {
  frmExpenseHead: FormGroup;
  today = this.calendar.getToday();
  submitted = false;

  txtCode: string;
  chkAutoCode: boolean = false;
  txtDate: NgbDateStruct;
  txtTitle: string;
  txtDescription: string;

  constructor(private calendar: NgbCalendar) { }

  ngOnInit() {    
    this.frmExpenseHead = new FormGroup({
      code: new FormControl("",[conditionalrequired(this.chkAutoCode)]),autoCode: new FormControl("")          
    });
  }

  get f() { return this.frmExpenseHead.controls; }

  onSubmit() {
    this.submitted = true;

    if (this.frmExpenseHead.invalid) {
      return;
    }

    alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.frmExpenseHead.value,null,4));
  }

  onReset() {
    this.submitted = false;
    this.frmExpenseHead.reset();
  }
}

自定义验证器是:

export function conditionalrequired(bValue: boolean): ValidatorFn {  
  return (control: AbstractControl): ValidationErrors | null => {

    let controlValue = control.value;    

    if (bValue === true) {      
      return null;
    }
    
    if (controlValue === "" || controlValue === null || controlValue === undefined) {
      return { "conditionrequired": true }
    }

    return null;
  }
}

谁能告诉我问题出在哪里?请按照以下链接查看可行的示例。

DEMO

解决方法

您不必为此创建自定义验证器,请使用可用工具。这对你来说会容易得多。

您可以订阅复选框 FormControl 的任何值更改,然后更改和更新您的输入 FormControl。下面是一个例子:

@Component({
  selector: 'app-my',templateUrl: './my.component.html',styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
  public fg: FormGroup;
  public checkbox: FormControl = new FormControl(false);
  public input: FromControl = new FormControl('',Validators.required);

  public constructor() { }

  public ngOnInit(): void {    
    this.fg = new FormGroup({
      checkbox: this.checkbox,input: this.input          
    });
    this.checkbox.valueChanges.subscribe(value => {
      if (value) {
        this.input.setValidators(null);
      } else {
        this.input.setValidators(Validators.required);
      }
      this.input.updateValueAndValidity();
    });
  }
}