有一个自定义输入组件,它以反应形式用于验证:
@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);
}
}
工作正常,我在反应式表单中使用custom-select
并希望如下所示验证它:
<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.myFrom = this.formBuilder.group({
country: [null, Validators.required],
})
但是当我为验证添加formControlName
时,会收到错误消息,其中没有值名称访问者,其名称为:&#39; country&#39; 。我该怎么办呢?
答案 0 :(得分:2)
步骤
在装饰器中添加 NG_VALUE_ACCESSOR 的提供者
在类中实现 ControlValueAccessor
像这样创建 onChange 函数 onChange = (value: boolean) => {};
添加 ControlValueAccessor 接口的 registerOnChange、writeValue 和 registerOnTouched 方法
在改变select值的方法中,调用onChange函数,将select的值作为参数传递。
var arr1 = ['banana', 'apple', 'orange', 'tomato', 'grape']
var arr2 = ['banana', 'grape']
arr2 = arr1.slice(0,2).filter( ( x ) => arr2.indexOf( x ) !== -1 )
console.log(arr2 = arr2.length > 0 ? arr2 : false)
不要忘记在选择器中添加 formControlName。
答案 1 :(得分:0)
将此添加到孩子的提供者:
viewProviders: [{
provide: ControlContainer,
useExisting: FormGroupDirective
}]
它首先失败的原因是它没有在 FormGroup 的父作用域中查找,所以这只是将它传递给子级。
然后你需要欺骗它认为你的控件有一个 valueAccessor——它不需要,因为你刚刚创建了一种“垫片”。
export const NOOP_VALUE_ACCESSOR: ControlValueAccessor =
{
writeValue(): void {},
registerOnChange(): void {},
registerOnTouched(): void {}
};
然后在您孩子的构造函数中:
constructor(@Self() @Optional() public ngControl: NgControl)
{
if (this.ngControl)
{
this.ngControl.valueAccessor = NOOP_VALUE_ACCESSOR;
}
}
然后你就可以在孩子内部正常使用 formControlName 了。
如果您需要从父组件传递 formControlName(如果它是一个可重用的控件,您可能会这样做)只需创建一个字符串 @Input
属性并在子组件中执行此操作:
<input matInput [placeholder]="desc"
[formControlName]="formControlName">