验证不会传播到 Angular 中的自定义表单控件 ng-select
Posted
技术标签:
【中文标题】验证不会传播到 Angular 中的自定义表单控件 ng-select【英文标题】:Validation is not propagate to Custom Form Control ng-select in Angular 【发布时间】:2020-06-12 23:43:55 【问题描述】:我在 Angular 9 应用程序中使用带有自定义表单控件的反应式表单。
我用自定义表单控件包装了我的 ng-select 控件。
我的验证有问题。我将 formControl 设置为必需。 Documentation says ng-invalid
css 类应该自动设置为 ng-select。但实际上使用自定义表单控件它不能正常工作。未设置 css 类,但设置了包装器类。我做错了什么还是这是图书馆的问题?
检查堆栈闪电战: https://stackblitz.com/edit/angular-rmvttg-ex63ka?file=src/forms-single-select-example.component.html&fbclid=IwAR2robtd_15khTVhmW59lLhn21HOHl_yYTrCWKaPRmfUt1QVvUn3n8V4Vjo
【问题讨论】:
【参考方案1】:DiPix,问题在于 Angular 将控件状态 CSS 类添加到您的自定义控件,而不是属于您的内部控件的 ng-select
您可以注入 ngControl 并检查 control.control.invalid 和 control.control.touched
constructor(private injector:Injector)
ngOnInit()
this.control = this.injector.get(NgControl);
然后你可以使用一些类似的
<ng-select #mySelect [ngClass]="'ng-invalid':control?.control.invalid,
'ng-touched':control?.control.touched"
....>
另一种方法是询问父母的班级。所以如果你定义了一个像
这样的getterget parentClass()
const match = /class=\"(.*?)\">/.exec(this.element.nativeElement.parentElement.innerHTML);
return match[0].split('"')[1]
constructor(private element:ElementRef)
你可以使用
<ng-select #mySelect [ngClass]="parentClass"
...>
你可以在your forked stackblitz看到
注意:无论如何,为了包装一个 ng-select,创建一个自定义表单控件是不必要的,只是一个带有 @Input 的 简单组件
@Input()control:any
你使用 as
<mycontrol [control]="someForm.get('someControl')"></mycontrol>
你可以看到this another stackblitz变得多么简单
【讨论】:
那么基本上什么时候应该使用自定义表单控件? 在我看来,如果向控件添加新的外观,自定义表单控件很有用。 datePicker 是“自定义表单控件”的一个很好的例子,多选是另一个很好的例子,或者一个仪表,或者一个在下拉时显示表格的组合,(我怀疑带有掩码的输入)或...... . 如果只想“分组”输入,例如询问号码、到期日期和 CVC 的信用卡-即使显示卡类型-或带有街道、城市、国家和 CP 的一组地址,我更喜欢使用组件。但实际上这只是个人意见。我只是 Angular 的业余爱好者 对我有意义。但我有一个小问题。我已经指示寻找formControlName
属性this.hostElement.nativeElement.nextElementSibling.attributes.formControlName
现在这样的元素不存在,因为我正在使用未在DOM 上显示的[control]
。知道如何获得 controlName 吗?【参考方案2】:
您可以通过Input
将FormGroup
向下传递到您的子组件并将其设置为ng-select
来解决此问题:
<mycontrol formControlName="someControl" [parentFormGroup]="someForm" ></mycontrol>
组件:
export class MyControlComponent implements ControlValueAccessor
@Input() parentFormGroup: FormGroup;
...
模板:
<ng-select #mySelect
[formGroup]="parentFormGroup"
...
【讨论】:
以上是关于验证不会传播到 Angular 中的自定义表单控件 ng-select的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 4 中,为啥异步验证的嵌套控件不会将其有效性传播到父 FormGroup?
Angular 6. 如何在创建的自定义控件中赋予验证状态这个控件?