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
});
有两种方法可以解决这个问题。
- 订阅 FormControl 的 valueChanges 事件。
- 订阅 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]);
}
}
我相信这很简单。 我有这个 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
});
有两种方法可以解决这个问题。
- 订阅 FormControl 的 valueChanges 事件。
- 订阅 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]);
}
}