繁体   English   中英

如何从 ControlValueAccessor 访问 NgControl

[英]How do you get Access to the NgControl from a ControlValueAccessor

我正在构建一个自定义组件,它实现了 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); 但在这种情况下,那种感觉就像一个黑客,不是吗?

您可以将NgControl注入到您的组件中。

constructor(@Self() @Optional() private ngControl: NgControl) {
    if (this.ngControl) {
      this.ngControl.valueAccessor = this;
    }
}

并删除NG_VALUE_ACCESSOR提供程序。

Angular2 DI 无法处理循环依赖。 这是构造函数注入 Angular2 使用的限制。 因此,你被黑客卡住了。

我不是专家,但我认为您正在尝试注入“自我”,这没有多大意义。 我遇到了类似的问题,我通过创建外部验证器指令解决了它,您可以在其中注入创建的 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);
}}

当您对组件本身或您可能使用的某些嵌套输入进行验证时,此方法都适用。

恕我直言,这是“正确”的方式,因为它将组件中的验证和逻辑之间的问题分开。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM