azu*_*net 6 typescript angular-validation angular angular7
我有一个用于动态创建表单的 Angular 7 项目。我有一个父 FormGroup,其中包含各种类型的嵌套 FormGroup。
我希望 ParentForm 无效,直到所有嵌套/子表单都有效(实际上希望它们提交但尚未到达)。
this.parentForm = new FormGroup(this.subforms, { validators: allSubModulesValidValidator });
Run Code Online (Sandbox Code Playgroud)
this.subforms 是一个像这样的对象:
interface DynamicKeyFormGroup {
[key: string]: FormGroup;
}
subforms: DynamicKeyFormGroup = {};
Run Code Online (Sandbox Code Playgroud)
我知道我的验证器是错误的,但我不知道如何为 FormGroup 和 FormControl 设计验证器。
我的想法是,我试图循环遍历所有 this.subForms 的属性(即嵌套的 FormGroups),然后检查它们的状态。如果有无效的,则将parentForm标记为无效。
const allSubModulesValidValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
const controls = control.controls;
for (const key in controls) {
if (controls.hasOwnProperty(key)) {
if (!(controls[key].status === 'valid')) {
return { 'allSubModulesValid': true };
}
}
}
return null;
};
Run Code Online (Sandbox Code Playgroud)
在我看来,这是角度上的一个错误,尽管如上面的评论所示,clearValidators这是预期的行为。
让我们看看发生了什么。
我假设您正在通过以下方式清除验证器(基于图像)
someControl.validator = null;
Run Code Online (Sandbox Code Playgroud)
这有点不合适,或者通过调用清除验证器函数,例如
someControl.clearValidators()
Run Code Online (Sandbox Code Playgroud)
根据角度源执行以下操作
/**
* Empties out the synchronous validator list.
*
* When you add or remove a validator at run time, you must call
* `updateValueAndValidity()` for the new validation to take effect.
*
*/
clearValidators(): void {
this.validator = null;
}
Run Code Online (Sandbox Code Playgroud)
正如此处所见,GithubSource是相同的。
所以问题是这个状态清除不会更新控件及其父控件的状态。
为了在清除状态后修复此行为,您应该更新控件
someControl.clearValidators();
someControl.updateValueAndValidity();
Run Code Online (Sandbox Code Playgroud)
updateValueAndValidity将更新控件的当前状态,并通知父级FormGroup(如果有)。
@jb-nizet 在上面的注释中提供的示例:即使您清除验证器,stackBlitzsetValue也会工作,因为他正在调用控件的方法,该方法执行以下操作
override setValue(value: TValue, options: {
onlySelf?: boolean,
emitEvent?: boolean,
emitModelToViewChange?: boolean,
emitViewToModelChange?: boolean
} = {}): void {
(this as {value: TValue}).value = this._pendingValue = value;
if (this._onChange.length && options.emitModelToViewChange !== false) {
this._onChange.forEach(
(changeFn) => changeFn(this.value, options.emitViewToModelChange !== false));
}
this.updateValueAndValidity(options);
}
Run Code Online (Sandbox Code Playgroud)
如Angular Source中所示,因此这将在内部调用updateValueAndValidity,从而更新状态。
3年后队长来了:D
| 归档时间: |
|
| 查看次数: |
1786 次 |
| 最近记录: |