自定义控件中的setValidators,无需Angular中的引用 [英] setValidators in custom control without from reference in Angular
问题描述
我已经创建了一个自定义输入控件.我不想创建任何自定义验证.我想使用默认必需的minLength,maxLength等.我知道我可以这样做
i have created a custom input control. I don't want to create any custom validation. I want to use default required, minLength, maxLength etc.I know i can do like this
this.form.controls["firstName"].setValidators([Validators.minLength(1), Validators.maxLength(30)]);
但是我无法从父组件发送表单引用.我如何在文本框组件内使用setValidator.
but i can't send form reference from parent component. How can i use setValidator inside textbox component.
// input-box.component.ts
import { Component, Input, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'app-input-box',
template:`<label >{{inputdata.label}}</label><br>
<input type="text" required #textBox [value]="textValue" (keyup)="onChange($event.target.value)" />`,
styleUrls: ['./input-box.component.less'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputBoxComponent),
multi: true
},
/*{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => InputBoxComponent),
multi: true,
}*/]
})
export class InputBoxComponent implements ControlValueAccessor {
@Input() inputdata: any;
private textValue: any = '';
onChange(value) {
this.textValue = value;
this.propagrateChange(value);
}
private propagrateChange = (_: any) => { };
writeValue(value: any) {
if (this.inputdata.value) {
this.textValue = this.inputdata.value;
this.propagrateChange(this.inputdata.value);
}
}
registerOnChange(fn: (value: any) => any) {
this.propagrateChange = fn;
}
registerOnTouched() { }
}
用于其他组件
<app-input-box name="textBoxParent_{{index}}" [inputdata]="goaldata" ngModel ></app-input-box>
推荐答案
如果要访问要实现ControlValueAccessor
的类中的FormControl
,则必须更改常规实现.您不能在providers数组中将类注册为ControlValueAccessor
,也不能在构造函数中注入FormControl
.因为FormControl将尝试注入您的类,并且您将尝试注入控件,这将创建循环依赖项.
If you want to access the FormControl
inside a class that wants to implement the ControlValueAccessor
you have to change your usual implementation. You cannot register the class as ControlValueAccessor
in the providers array AND inject the FormControl
in the constructor. Because the FormControl will try to inject your class, and you will try to inject the control, which will create a circular dependency.
因此,您需要进行的更改如下:
So the changes you need to make are as follows:
- 从
providers
阵列中删除NG_VALUE_ACCESSOR
和NG_VALIDATORS
. -
在构造函数中注入
NgControl
并设置控件的ControlValueAccessor和Validators.
- Remove
NG_VALUE_ACCESSOR
andNG_VALIDATORS
from theproviders
array. Inject
NgControl
in the constructor and set the control's ControlValueAccessor and Validators.
constructor(@Self() ngControl: NgControl) {
ngControl.valueAccessor = this;
ngControl.setValidators([Validators.minLength(1), Validators.maxLength(30)]
ngControl.updateValueAndValidity()
}
如果要保留自定义表单组件的使用者指定的验证器,则需要将构造函数修改为:
If you want to keep the validators specified by the consumer of your custom form component you need to modify the constructor to this:
constructor(@Self() ngControl: NgControl) {
const control = ngControl.control;
let myValidators = [Validators.required, Validators.minLength(5)];
let validators = control.validator
? [control.validator, ...myValidators]
: myValidators;
control.setValidators(validators)
control.updateValueAndValidity();
}
在AngularConnect 2017上查看Kara Erickson(角核)解释的整个过程.链接
Check out the whole process explained by Kara Erickson (angular core) at AngularConnect 2017. Link
这篇关于自定义控件中的setValidators,无需Angular中的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!