我知道如何通过两种方式做到这一点(此处两种方式的演示)。两者都适用于模板驱动和反应式表单,因为它们都依赖于
FormGroup
API。
formGroup.enable()
和 formGroup.disable()
<form ngForm>
<input ngModel name=name [disabled]=fieldIsDisabled() />
</form>
this.ngForm.form.enable();
this.ngForm.form.disable();
如果不是因为两个问题,我希望我可以使用这种方法:
formGroup.enable()
忽略字段的 [disabled]
指令值,因此当其他控件可能要求其保持禁用状态时强制所有字段启用。这显示在链接的演示中。[disabled]
指令中的值发生变化,表单字段不会关心我是否调用 enable()
或 disable()
,这可能会导致字段在我不希望它们启用时启用。我希望它像控制变量一样工作,就像下一个解决方案:
这里,
formIsDisabled
信号控制整个表单的“禁用”状态。它解决了之前解决方案的问题。
<form ngForm>
<input ngModel name=name [disabled]="formIsDisabled() || nameDisabled()"/>
<input ngModel name=address [disabled]=formIsDisabled() />
</form>
缺点是控制变量必须应用于每个字段,这感觉冗余且容易出错...但据我所知,它仍然是最不坏的选择。
formGroup.enable()
和formGroup.disable()
方法如此工作的原因是什么?仅使用DISABLED状态来实现这一点的方法:
为了简单起见,假设您有一维反应形式。首先,您需要禁用所有当前启用的字段并收集禁用字段的键:
const alreadyDisadledKeys: string[] = [];
Object.keys(this.form.controls).forEach((key) => {
const control = this.form.controls[key];
if (control.status === 'DISABLED') {
alreadyDisadledKeys.push(key);
} else {
control.disable();
}
});
已经DisadledKeys可以存储在某处。然后再次启用表单,排除alreadyDisadledKeys:
Object.keys(this.form.controls).forEach((key) => {
const control = this.form.controls[key];
if (!alreadyDisadledKeys.includes(key)) {
control.enable();
}
});
同样的方法也可以扩展到更复杂的形式,您需要执行相同的步骤:
formGroup.enable() 和 formGroup.disable() 方法这样工作有什么原因?
这里我只能猜测。我认为这是因为 Angular 将 DISABLED 视为一种状态而不是一种属性。