Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
341 views
in Technique[技术] by (71.8m points)

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

I am sure this is simple. I have this 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>

I am trying to only enable the endDate if the rolling is toggled off.

I have tried doing it like this:

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,
    })
  );
}

But when I toggle the slider, nothing happens. The input is always disabled. Does anyone know why?

question from:https://stackoverflow.com/questions/65848341/angular-cant-disabled-a-control-using-reactive-forms-and-a-boolean-with-angula

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Example reproduced and resolved at: https://stackblitz.com/edit/angular-ivy-h4wyta?file=src/app/app.component.ts

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

Simply this won't work. You have to detect the changes on toggle.

First of all simplify the form initialization.

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
});

And there is two ways to resolve the issue.

  1. Subscribe to FormControl's valueChanges event.
  2. Subscribe to MatSlideToggle's OnChange event.

Way 1:

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

Way 2:

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

Then you have to do the disable work.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...