Angular 无法使用反应形式和布尔值禁用控件(使用 angular material)

Angular Can't disabled a control using reactive forms and a boolean (with angular material)

我相信这很简单。 我有这个 html:

<form [formGroup]="formGroup">
    <mat-form-field class="form-group" appearance="outline">
        <mat-label>Choose your start date</mat-label>
        <input matInput formControlName="startDate" aria-label="startDate"
            [matDatepicker]="start">
        <mat-datepicker-toggle matSuffix [for]="start"></mat-datepicker-toggle>
        <mat-datepicker #start></mat-datepicker>
    </mat-form-field>

    <mat-form-field class="form-group" appearance="outline">
        <mat-label>End date</mat-label>
        <input matInput formControlName="endDate" aria-label="endDate" [matDatepicker]="end">
        <mat-datepicker-toggle matSuffix [for]="end"></mat-datepicker-toggle>
        <mat-datepicker #end></mat-datepicker>
    </mat-form-field>

    <div class="form-group">
        <mat-slide-toggle formControlName="rolling">Continue until further notice?
        </mat-slide-toggle>
    </div>
</form>

如果 rolling 已切换 off,我将尝试仅启用 endDate

我试过这样做:

public formGroup: FormGroup;
public subscription: Subscription;

// convenience getter for easy access to form fields
get f() {
  return this.formGroup.controls;
}

constructor(
  private formBuilder: FormBuilder
) {}

ngOnInit(): void {
  this.createForm();
}

private createForm(): void {
  this.formGroup = this.formBuilder.group({
    startDate: new FormControl(
      this.subscription.startDate,
      Validators.required
    ),
    rolling: this.subscription.rolling,
  });
  this.formGroup.addControl(
    'endDate',
    new FormControl({
      value: this.subscription.endDate,
      disabled: this.f.rolling.value === true,
    })
  );
}

但是当我切换滑块时,没有任何反应。输入始终被禁用。有谁知道为什么?

由于rolling是表格的一部分,你可以像下面这样写并尝试:

this.formGroup = this.formBuilder.group({
    startDate: new FormControl(
      this.subscription.startDate,
      Validators.required
    ),
    rolling: new FormControl(this.subscription.rolling)
  });

我想你忘了提到 rolling new FormControl()

示例复制并解决于:https://stackblitz.com/edit/angular-ivy-h4wyta?file=src/app/app.component.ts

disabled: this.f.rolling.value === true

这根本行不通。您必须检测切换时的变化。

首先简化表单初始化。

this.formGroup = this.formBuilder.group({
   startDate: new FormControl(this.testObject.startDate, Validators.required),
   endDate: new FormControl(this.testObject.endDate, Validators.required),
   rolling: this.testObject.rolling
});

有两种方法可以解决这个问题。

  1. 订阅 FormControl 的 valueChanges 事件。
  2. 订阅 MatSlideToggle 的 OnChange 事件。

方式一:

this.formGroup.get("rolling").valueChanges.subscribe(value => {
   this.rollingChanged(value);
});

方式二:

onChange() {
   const value = this.formGroup.get("rolling").value;
   this.rollingChanged(value);
}

然后你要做禁用工作。

rollingChanged(value: boolean) {
    const control = this.formGroup.get("endDate");
    if (value) {
      control.reset();
      control.clearValidators();
      control.disable();
    } else {
      control.enable();
      control.setValidators([Validators.required]);
    }
}