我正在构建一个自定义组件,它实现了ControlValueAccessor,因此我可以在我的from中使用ngControl和ngModel。现在我想要逻辑来验证组件是否在其自身内(因此它是自包含的)。到目前为止一切都那么好,但现在我有一个循环依赖,因为我试图在一个组件中注入NgControl(设置外部表单状态),并自我注入一个 CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR 供应商。代码如下:
const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR = new Provider(
NG_VALUE_ACCESSOR, {
useExisting: forwardRef(() => CustomInput),
multi: true
});
@Component({
moduleId: module.id,
selector: 'custom-input',
templateUrl: 'custom-input.html',
styleUrls: ['custom-input.css'],
directives: [CORE_DIRECTIVES],
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CustomInput implements ControlValueAccessor{
private _text: any = '';
public isValid:boolean = false;
onChange: EventEmitter<any> = new EventEmitter();
onTouched: any;
constructor(private ngControl:NgControl) {
}
onToggle(){
this.isValid = !this.isValid;
let res = this.isValid? null:{ "test": true };
this.ngControl.control.setErrors(res);
}
get text(): any { return this._text; };
set text(v: any) {
if (v !== this._text) {
this._text = v;
this.onChange.emit(v);
}
}
writeValue(v) {
this.text = v;
}
registerOnChange(fn): void {
this.onChange.subscribe(fn);
}
registerOnTouched(fn): void {
this.onTouched = fn;
}
}
如何从组件中获取对ngControl的引用?我知道你可以这样做:
this.ngControl = this._injector.get(NgControl, null);
但在这种情况下,这种感觉就像黑客一样吗?
答案 0 :(得分:2)
您可以将NgControl
注入组件。
constructor(@Self() @Optional() private ngControl: NgControl) {
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
}
并删除NG_VALUE_ACCESSOR
提供程序。
答案 1 :(得分:0)
Angular2 DI无法处理循环依赖。这是Angular2使用的构造函数注入的限制。因此,你坚持使用黑客。
答案 2 :(得分:0)
我不是专家,但我认为你正试图注入'自我',这没有多大意义。我有类似的问题,我通过创建外部解决了它 Validator指令,您可以在其中注入创建的ngControl。
@Directive({
selector: '[customValidate][ngModel],[customValidate][formControl]',
providers: [
provide(NG_VALIDATORS, {
useExisting: forwardRef(() => CustomValidator),
multi: true
})
]})
export class CustomValidator {
validator: Function;
constructor() {
this.validator = SOME_VALIDATION_FUNCTION;
}
validate(c: NgControl) {
// use injected ngControl
return this.validator(c);
}}
当您对组件本身进行验证时,或者对您可能使用的某些嵌套输入进行验证时,此方法都适用。
恕我直言,这是'正确'的方式,因为它分离了你组件中验证和逻辑之间的关注。