【问题标题】:Extending FormControlDirective in Angular 2+在 Angular 2+ 中扩展 FormControlDirective
【发布时间】:2018-09-01 13:12:51
【问题描述】:

我正在看这个问题,试图弄清楚如何扩展 FormControlDirective:Attempting to extend FormControlDirective to implement my own FormControl directive results in faulty binding

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

formControl \ formControlName 选择器又出现在一个 地点-the value accessor。 为了使您的指令起作用,您应该实现所有默认值 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 非常相似。 set appControl 确实运行,即使我传递了像 &lt;input type="text" class="form-control" appControl="firstName"&gt; 这样的值,而 FormControlDirective._rawValidators 似乎总是一个空数组,即使 FormGroup 与标准 FormControlDirective 一起使用。

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

【问题讨论】:

    标签: angular angular-directive angular-reactive-forms angular-forms


    【解决方案1】:

    如果其他人遇到这样的事情,这是我想出的解决方案。我想从子表单控件元素动态创建表单控件模型。这样我就不必编写包含大量表单控制字段的初始模型,同时仍能从反应式表单模型中受益。这是扩展 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      • 2018-12-31
      • 1970-01-01
      • 2016-03-22
      • 1970-01-01
      相关资源
      最近更新 更多