在 Angular 6 中重置反应式表单时不会禁用输入 [英] Input does not disable on resetting a Reactive Form in Angular 6
问题描述
我针对我的问题创建了一个StackBlitz 示例.
I have created a StackBlitz example of my problem.
我有一个构建表单的FormService
,由initForm()
方法中的组件获取:-
I have a FormService
that builds a form, which is obtained by the component in the initForm()
method:-
public getForm() {
return this.fb.group({
cb1: this.fb.control(false),
cb2: this.fb.control(false),
inputBox: this.fb.control({value: '', disabled: true}, Validators.required)
});
}
如果没有选中任何复选框,我需要禁用输入文本框.这让我做这样的事情:-
I need to disable the input text box if none of the checkboxes is selected. Which brings me to do something like this :-
if(!this.cb1.value && !this.cb2.value) {
this.isCheckboxSelectionInvalid = true;
this.inputBox.disable();
} else {
this.isCheckboxSelectionInvalid = false;
this.inputBox.enable();
}
这适用于所有默认场景 - 但是有一个问题.当我调用 resetForm()
(前提是通过选中其中一个复选框启用输入)时,它基本上调用了与 initForm()
相同的方法,输入保持启用状态.即使在我调用验证复选框选择并禁用 initForm()
方法中的输入的方法之后也是如此.
This works for all default scenarios - however there is a problem. When I call resetForm()
(provided the input is enabled by checking one of the checkboxes) which basically calls the same method of initForm()
, the input stays enabled. This is even after I call the method that validates checkbox selection and disables the input in the initForm()
method.
为了理智,我记录了输入的 disabled
属性的值 - 记录 true
.
For sanity, I logged the value of the input's disabled
property - which logs true
.
为什么输入没有被禁用呢?任何帮助将不胜感激,这是工作中的问题.
Why is it that the input doesn't get disabled then? Any help would be very appreciated, this is a problem at work.
推荐答案
您遇到的问题与 angular bug 有关,您可以找到更多信息 此处.
The problem you are facing is related to an angular bug, you can find more info here.
有一些解决方法对我有用:
- 在 setTimeout 中调用禁用函数.
validateCheckboxSelectionAndChangeInputState() {
if (!this.cb1.value && !this.cb2.value) {
this.isCheckboxSelectionInvalid = true;
setTimeout(() => {
this.inputBox.disable();
}, 0);
} else {
this.isCheckboxSelectionInvalid = false;
this.inputBox.enable();
}
}
- 直接设置禁用属性:
<input type="text" [attr.disabled]="form.controls['inputBox'].disabled" formControlName="inputBox" />
- 在调用启用/禁用函数之前调用detectChanges.
validateCheckboxSelectionAndChangeInputState() {
this.ref.detectChanges();
if (!this.cb1.value && !this.cb2.value) {
this.isCheckboxSelectionInvalid = true;
this.inputBox.disable();
} else {
this.isCheckboxSelectionInvalid = false;
this.inputBox.enable();
}
}
与问题无关的建议:
有了启用或禁用控件的想法,可以订阅表单valueChanges:
With the idea of enabling or disabling the control, you can subscribe to form valueChanges:
initForm() {
this.form = this.formService.getForm();
this.cb1 = this.form.get("cb1");
this.cb2 = this.form.get("cb2");
this.inputBox = this.form.get("inputBox");
this.form.valueChanges.subscribe(
this.validateCheckboxSelectionAndChangeInputState.bind(this)
);
}
validateCheckboxSelectionAndChangeInputState(controls) {
if (this.inputBox.disabled && controls.cb1 && controls.cb2) {
this.inputBox.enable();
}
if(this.inputBox.enabled && !controls.cb1 && !controls.cb) {
setTimeout(() => {
this.inputBox.disable();
}, 0);
}
}
toggleCb1() {
this.cb1.setValue(!this.cb1.value);
}
toggleCb2() {
this.cb2.setValue(!this.cb2.value);
}
resetForm() {
this.initForm();
}
你也可以[禁用]使用form.valid和Validators.requiredTrue的按钮:
Also you can [disabled] the button using form.valid, and using the Validators.requiredTrue:
html
<button [disabled]="!form.valid" (click)="submitForm()">
Submit
</button>
ts
public getForm() {
return this.fb.group({
cb1: this.fb.control(false, [Validators.requiredTrue]),
cb2: this.fb.control(false, [Validators.requiredTrue]),
inputBox: this.fb.control(
{ value: "", disabled: true },
[Validators.required]
)
});
}
参见 https://stackblitz.com/edit/angular-6-reactive-form-disable-jn4cf8?file=src%2Fapp%2Fapp.component.ts
这篇关于在 Angular 6 中重置反应式表单时不会禁用输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!