我试图构建一个角度组件以包裹整个Angular Material的mat-form-field。
<mat-form-field>
<input matInput type="text" placeholder="{{ label }}" [(ngModel)]="_value"
[required]="required" [disabled]="_disabled"
(input)="intenrnalValueChange()" />
<mat-hint>{{ hint }}</mat-hint>
<mat-error>{{ getError() }}</mat-error>
</mat-form-field>
该组件运行良好,但有一点麻烦。我无法将其标记为“感动”,我相信这是由于组件体系结构所致。我已经尝试了一些StackOverflow解决方案(和其他解决方案),这些解决方案在传统方式下效果很好,但不适用于我的组件。
this.form.get('field').markAsTouched(); // should work
this.form.markAsTouched(); // should not work
this.form.markAllAsTouched(); // should work
我想标记一个按钮触摸过的字段,该按钮将显示所有仍然无效的字段(并通过错误提示其消息)。
我创建了一个简化的项目,可以在其中重现该问题。我希望单击按钮时该字段变为红色,并且消息显示在下面。不会发生,但是如果单击并模糊该字段,则会显示错误。
https://stackblitz.com/edit/angular-7mghym
问题是:如何更改我的项目(保留组件)以使按钮具有单击和模糊字段的相同效果?
答案 0 :(得分:1)
您的方法有几个问题;
首先,您正在实现ControlValueAccessor
,但是您的InputComponent
有一个名为formControl的@Input
。因此,当您将form.controls.field
绑定到app-input
时,您的表单不会与ControlValueAccessor进行交互。
<app-input label="Test" hint="It is a test" [formControl]="form.controls.field" required></app-input>
如docs中所述;
ControlValueAccessor充当Angular表单API与DOM中的本机元素(html输入元素)之间的桥梁
第二个问题出现在这里; InputComponent
中的DOM(html输入元素)和ControlValueAccessor
之间的通信是通过ngModel
处理的,而FormControl
基本上是引擎盖下显式创建的form.controls.field
的包装。
这些的结果; this.form.get('field').markAsTouched();
FormControl与ngModel实际的输入元素没有通信。因此,当您手动聚焦/模糊输入元素时,它会显示错误状态,但是ControlValueAccessor
却什么也没做。
第三个问题是;即使您通过从@Input formControl
中删除InputComponent
使ngModel
正常工作,并与没有mat-form-field
的html输入进行通信;不过,input
将无法与基础ControlValueAccessor
元素进行交互(即获取错误状态),因为它需要实现MatFormFieldControl
第四个问题是,在使用ReactiveForms时,必须通过FormControl而不是隐式地处理验证(如您所需要的验证)和禁用状态。
好消息是,所有这些问题都有一个非常简单的解决方案,无需实施$request->get()
,只需将formControl传递给InputComponent并将其绑定到html输入即可。
这是一个可行的例子; https://stackblitz.com/edit/angular-fwdrv9
希望对您有帮助,祝您有愉快的一天。