angular2-template - 当未在NgIf中呈现时,删除角度4中的验证

标签 angular2-template angular-directive angular4-forms angular-validation

我想删除使用NgIf无法呈现控件的验证。我尝试使用伪指令使用隐藏控件删除,但无法执行相同操作,因为它不在模板中呈现。因此,我无法在指令中使用ElementRef来检查formControlName。这是ts文件

this.form = this._fb.group({
  text1: ['', Validators.required],
  text2:  ['', Validators.required]
});

和模板
<form[formGroup]="form">
  <input type="text" formControlName="text1">
 <div *ngIf="false">
  <input type="text" formControlName="text2">
</div>

我想动态且全局地删除text2的验证。不删除ts文件中的验证器。

最佳答案

Kara的Angular源GitHub Issue评论似乎非常相关,它说明了如何通过将 react 模型视为“真相源”并从该真相源(而不是相反)创建ngIf表达式来解决问题。这表明这是设计使然,您必须做出一些努力,以免混淆模板驱动和 react 性表单的想法。

https://github.com/angular/angular/issues/7970#issuecomment-228624899

Thanks for taking the time to describe the problem. I took a look at your example code, and it seems that you are using the reactive form directives (a.k.a "model-driven" directives: ngFormModel, etc), but a template-driven strategy. The fact that the ngIf does not remove the control from the form's serialization and validation is actually by design, and here's why.

In each form paradigm - template-driven and reactive - there can only be one source of truth for the list of active controls. In the template-driven paradigm, the source of truth is the template. In the reactive equivalent, the source of truth is the form model created in the parent component. The DOM does not dictate the state of your form. For this reason, if you remove form control elements from the DOM while using a reactive approach, the form controls are not necessarily changed in the source of truth unless you want them to be. You can choose to update the controls imperatively by calling this.form.removeControl('controlName'), or you can choose to keep the controls in your form. This flexibility allows you to add or remove inputs from the DOM temporarily while keeping their form values serialized (e.g. if you have a number of collapsible sections to your form, you can remove sections on collapse without impacting the value of your form). We don't want to restrict this flexibility and complicate ownership by forcing the model to always match the DOM.

So in your case, if you choose a reactive strategy, you'll want to invert your logic to rely on the source of truth - the model. Specifically, this means removing the control imperatively in the model by calling this.form.removeControl('name') when the button is clicked. Then, the ngIf should depend on the control's presence in the model with *ngIf="form.contains('name')", rather than the other way around. See example plunker here: http://plnkr.co/edit/V7bCFLSIEKTuxU9jcp6v?p=preview

It's worth noting that if you're still using beta.14 (as in your plunker), you'll need to call this.form.updateValueAndValidity() manually. This requirement was removed in #9097, so versions after RC.2 don't require the call.

Another option is to convert to a template-driven strategy (no ngFormModel), which will remove the control from the form when it's destroyed from the template. Example: http://plnkr.co/edit/s9QWy9T8azQoTZKdm7uI?p=preview

I'm going to close this issue as it works as intended, but I think we could make the experience a lot friendlier. A good start would be some more cookbooks and guides in the documentation.

关于angular2-template - 当未在NgIf中呈现时,删除角度4中的验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49973236/

相关文章:

html - 用蓝色突出显示 div 中的文本

angular - 为什么 mat-select 不能在模态内工作? onclick 它显示模态后面的选项

Angular - 如何从指令访问和替换 innerHTML

apache - 当 ng build dist 文件夹(重命名为 myapp)部署在 tomcat webapp 文件夹中时,Angular 2 无法加载图像

javascript - 如何捕获指令中的复选框事件?

javascript - 如何在angular4中设置下拉值?

Angular 5 - 表单验证电子邮件

javascript - 通过包含缺失的月份来显示 *ngFor 中的月份序列

Angular 2 路由在部署到 Http 服务器时不起作用

angular - 响应式(Reactive)表单确认密码和确认电子邮件验证器 Angular 4