将 formControlName 用于反应形式的自定义输入组件 [英] use formControlName for custom input component in reactive form
本文介绍了将 formControlName 用于反应形式的自定义输入组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
有一个自定义输入组件,它以带有验证的反应形式使用:
@Component({moduleId: module.id.toString(),选择器:'自定义选择',templateUrl: 'custom-select.component.html',styleUrls: ['custom-select.component.css']})导出类 CustomSelectComponent {@Input() 公共项:SelectModel[];公共模型:SelectModel;构造函数(私有自定义选择服务:自定义选择服务){this.customSelectService.Selected.subscribe((data: SelectModel) => {this.model = 数据;});}公共新选择(选择:SelectModel):无效{this.customSelectService.updateSelected(select);}}
工作正常,我在反应形式中使用 custom-select
并想像下面一样验证它:
</custom-select><div *ngIf=" myFrom.controls['country'].invalid && (myFrom.controls['country'].dirty||myFrom.controls['country'].touched) " class="ha-control-alert"><div *ngIf="myFrom.controls['country'].hasError('required')">国家/地区为必填项
这就是我在组件中声明表单的方式
this.myFrom = this.formBuilder.group({国家:[null,Validators.required],})
但是当我添加 formControlName
进行验证时,它会收到错误消息,显示没有名称的表单控件的值访问器:'国家'.我该如何处理?
解决方案
STEPS
- 在装饰器中添加 NG_VALUE_ACCESSOR 的提供者
- 在类中实现 ControlValueAccessor
- 像这样创建 onChange 函数 onChange = (value: boolean) =>{};
- 添加 ControlValueAccessor 接口的 registerOnChange、writeValue 和 registerOnTouched 方法
- 在更改select值的方法中,调用onChange函数,将select的值作为参数传递.
导入 ...从@angular/core"导入 { Component, forwardRef };从@angular/forms"导入 { ControlValueAccessor, NG_VALUE_ACCESSOR };@成分({moduleId: module.id.toString(),选择器:'自定义选择',templateUrl: 'custom-select.component.html',styleUrls: ['custom-select.component.css'],//第1步提供者:[{提供:NG_VALUE_ACCESSOR,多:真实,useExisting: forwardRef(() => CustomSelectComponent)}]})//第2步导出类 CustomSelectComponent 实现 ControlValueAccessor {//第 3 步onChange = (value: SelectModel) =>{};@Input() 公共项:SelectModel[];公共模型:SelectModel;构造函数(私有 customSelectService:CustomSelectService){this.customSelectService.Selected.subscribe((data: SelectModel) => {this.model = 数据;});}公共新选择(选择:SelectModel):无效{//第 5 步this.onChange(选择);this.customSelectService.updateSelected(select);}//第四步registerOnChange(fn: (value: SelectModel) => void): void {this.onChange = fn;}写值(){}registerOnTouched(){}}
不要忘记在选择器中添加 formControlName.
There is a custom input component and it is used in a reactive form with validation:
@Component({
moduleId: module.id.toString(),
selector: 'custom-select',
templateUrl: 'custom-select.component.html',
styleUrls: ['custom-select.component.css']
})
export class CustomSelectComponent {
@Input() public items: SelectModel[];
public model: SelectModel;
constructor(private customSelectService: CustomSelectService) {
this.customSelectService.Selected.subscribe((data: SelectModel) => {
this.model = data;
});
}
public newSelect(select: SelectModel): void {
this.customSelectService.updateSelected(select);
}
}
which works fine, I am using custom-select
in a reactive form and want to validate it like below:
<custom-select id="country" [items]="selectItems" formControlName="country"></custom-select>
<div *ngIf=" myFrom.controls['country'].invalid && (myFrom.controls['country'].dirty
|| myFrom.controls['country'].touched) " class="ha-control-alert">
<div *ngIf="myFrom.controls['country'].hasError('required')">Country is required</div>
</div>
this is how I declare the form in component
this.myFrom = this.formBuilder.group({
country: [null, Validators.required],
})
but when I add formControlName
for validations, it gets error which says No value accessor for form control with name: 'country'. How should I handle this?
解决方案
STEPS
- Add the provider for NG_VALUE_ACCESSOR in the decorator
- Implement the ControlValueAccessor in the class
- Create the onChange function like this onChange = (value: boolean) => {};
- Add the registerOnChange, writeValue and registerOnTouched methods of the ControlValueAccessor interface
- In the method that will be changed the value of select, call the onChange function passing as parameter the value of select.
import ...
import { Component, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
moduleId: module.id.toString(),
selector: 'custom-select',
templateUrl: 'custom-select.component.html',
styleUrls: ['custom-select.component.css'],
// STEP 1
providers: [{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => CustomSelectComponent)
}]
})
// STEP 2
export class CustomSelectComponent implements ControlValueAccessor {
// STEP 3
onChange = (value: SelectModel) => {};
@Input() public items: SelectModel[];
public model: SelectModel;
constructor(private customSelectService: CustomSelectService) {
this.customSelectService.Selected.subscribe((data: SelectModel) => {
this.model = data;
});
}
public newSelect(select: SelectModel): void {
// STEP 5
this.onChange(select);
this.customSelectService.updateSelected(select);
}
// STEP 4
registerOnChange(fn: (value: SelectModel) => void): void {
this.onChange = fn;
}
writeValue() {}
registerOnTouched(){}
}
Don't forget to add the formControlName in the selector.
这篇关于将 formControlName 用于反应形式的自定义输入组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文