angular - 从父组件动态设置子表单验证器
问题描述
我一直在 Angular 8 中创建可重用的子表单,并且使用 为子表单FormGroupDirective
获取父表单的引用FormGroup
很容易完成,但我很难弄清楚如何在子表单上动态设置验证器从父母。
使用ngAfterViewInit
我可以看到子表单的表单控件已添加到父表单,但我似乎无法直接从父表单更新默认子表单验证器。
// PARENT COMPONENT
public ngAfterViewInit() {
// Form controls have been applied to the form group
console.log('ngAfterViewInit', this.form.value);
// BUT the validators of profile form aren't being set?
this.form.get('profile').get('description').setValidators([Validators.required]);
}
我创建了我的示例代码的StackBlitz。除配置文件描述外的所有字段均为必填字段并具有默认值。因此,无需对验证器进行任何更改,表单将在提交时通过验证并在控制台中输出VALID 。在ngAfterViewInit
我将描述字段验证器设置为必需,这应该防止表单被提交并在控制台中输出INVALID,但它仍然提交并输出VALID。
是否可以动态设置子表单的验证器而不通过@Input
绑定传递它们?
解决方案
显然,您只需要使用updateValueAndValidity
已更改的表单控件即可。
this.form.get('profile').get('description').updateValueAndValidity();
所以它最终看起来像这样:
public ngAfterViewInit() {
// Form controls will now exist
console.log('ngAfterViewInit', this.form.value);
// BUT the validators of the profile form should not allow submission if set to required, and they do?
this.form.get('profile').get('description').setValidators([Validators.required]);
this.form.get('profile').get('description').updateValueAndValidity();
}
当你这样做时,你会在控制台中看到一个错误,上面写着:
ERROR
Error: ExpressionChangedAfterItHasBeenCheckedError:
Expression has changed after it was checked.
Previous value: 'ng-valid: true'. Current value: 'ng-valid: false'.
这可以通过使用ChangeDetectorRef
和调用来克服this.changeDetector.detectChanges()
,或者通过将父组件的更改检测策略更新为ChagneDetectionStrategy.OnPush
.
constructor(private changeDetector: ChangeDetectorRef) { }
// Removed for brevity
public ngAfterViewInit() {
const descControl = this.form.get('profile').get('description');
descControl.setValidators([Validators.required]);
descControl.updateValueAndValidity();
this.changeDetector.detectChanges();
}
@Component({
selector: 'app-page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PageComponent implements OnInit, AfterContentInit, AfterViewInit {
// Removed for brevity
public ngAfterViewInit() {
const descControl = this.form.get('profile').get('description');
descControl.setValidators([Validators.required]);
descControl.updateValueAndValidity();
}
}
推荐阅读
- cakephp - 使用控制器中的另一个操作处理发布操作
- debian - dh: 无法加载插件配置包
- c# - c# DataTable Linq Group by Multiple column sum int and timespan
- yadcf - 使用 yadcf 时 auto_complete 功能不使用 filter_plugin_options
- javascript - javascript中macos应用程序的API文档?
- node.js - 在版本 5 中,最大调用堆栈大小超过了 mongoose
- r - 在某个模式之前对字符串的一部分进行子集
- python - 使用 Q 对象时出现 FieldError - 无法将关键字 __ 解析为字段
- php - 使用条件语句获取相关模型的唯一计数
- javascript - 如何修复html中的thead或table列?