在 Angular 2+ 中扩展 FormControlDirective

2024-01-08

我正在看这个问题,试图弄清楚如何扩展 FormControlDirective:尝试扩展 FormControlDirective 来实现我自己的 FormControl 指令会导致绑定错误 https://stackoverflow.com/questions/44812220/attempting-to-extend-formcontroldirective-to-implement-my-own-formcontrol-direct.

有一个答案,但我不确定是什么意思:

The formControl \ formControlName选择器出现在另一个 地方 -价值 存取器 https://github.com/angular/angular/blob/master/packages/forms/src/directives/default_value_accessor.ts#L47。 为了让你的指令发挥作用,你应该实现所有默认值 的访问器hybridFormControl指令(遵循 内置指令的模式)。

这是我的代码:

export const formControlBinding: any = {
  provide: NgControl,
  useExisting: forwardRef(() => ControlDirective)
};

@Directive({
  selector: '[appControl]',
  providers: [formControlBinding],
  exportAs: 'ngForm'
})
export class ControlDirective extends FormControlDirective implements OnInit {

  constructor(
    @Optional() @Self() @Inject(NG_VALIDATORS) validators: Array<Validator|ValidatorFn>,
    @Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: Array<AsyncValidator|AsyncValidatorFn>,
    @Optional() @Self() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[],
    public renderer: Renderer2,
    public hostElement: ElementRef,
  ) {
    super(validators, asyncValidators, valueAccessors);
  }

  @Input() set appControl(form: FormControl) {
    console.log(form);
    this.form = form;
  }
}

它与@ronif的非常相似Plunker https://plnkr.co/edit/9IHXCKzVqLJTDM4A2iWc?p=info从他的问题来看。set appControl确实运行,即使我传递了一个类似的值<input type="text" class="form-control" appControl="firstName">, and FormControlDirective._rawValidators似乎总是一个空数组,即使FormGroup符合标准FormControlDirective.

我将如何“实现所有默认值访问器”?


如果其他人遇到类似的情况,这是我想出的解决方案。我想从子表单控件元素动态创建表单控件模型。这样我就不必编写包含大量表单控制字段的初始模型,同时仍然可以获得反应式表单模型的好处。这是扩展 FormControlName 类的方法:

@Directive({
  selector: '[hybridFormControl]'
})
class HybridFormControl Directive extends FormControlName implements ControlValueAccessor, OnChanges {
  @Input('hybridFormControl') name: string;

  onChange;
  onTouched;

  constructor(
      @Optional() protected formGroupDirective: FormGroupDirective,
      @Optional() @Self() @Inject(NG_VALUE_ACCESSOR) valueAccessors: ControlValueAccessor[],
      private fb: FormBuilder,
      private renderer: Renderer2,
      private element: ElementRef
  ) {
    super(formGroupDirective, [], [], valueAccessors, null);
    this.valueAccessor = this;
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (!this._registered) {
      // dynamically create the form control model on the form group model.
      this.formGroup = this.formGroupDirective.form;
      this.formGroup.registerControl(name, this.fb.control(''));
      this._registered = true;
    }

    // IMPORTANT - this ties your extended form control to the form control 
    // model on the form group model that we just created above. Take a look
    // at Angular github source code.
    super.ngOnChanges(changes); 
  }

  @HostListener('input', ['$event.target.value'])
  @HostListener('change', ['$event.target.value'])
  onInput(value): void {
    this.onChange(modelValue);
  }

  writeValue(value): void {
    const element = this.element.nativeElement;
    this.renderer.setProperty(element, 'value', value);
  }

  registerOnChange(fn): void {
    this.onChange = fn;
  }

  registerOnTouched(fn): void {
    this.onTouched = fn;
  }
}

您将使用这个新的混合指令,例如:

@Component({
  selector: 'app',
  template: `
    <form formGroup=[formGroup]>
      <input type="text" hybridFormControl="myName">
    </form>
  `
class AppComponent {
  formGroup: FormGroup

  constructor(fb: FormBuilder) {
    this.form = this.fb.group({});
  }
}

您将需要修改this.formGroup.registerControl(name, this.fb.control(''));如果您想通过验证器,请添加一行代码。我尚未验证这一点,但希望这对遇到此问题的其他人有所帮助。

资料来源:https://github.com/angular/angular/blob/master/packages/forms/src/directives/reactive_directives/form_control_name.ts#L212 https://github.com/angular/angular/blob/master/packages/forms/src/directives/reactive_directives/form_control_name.ts#L212

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Angular 2+ 中扩展 FormControlDirective 的相关文章

随机推荐