Angular 7:将指令生成的包装组件绑定到外部表单

时间:2019-05-14 06:53:56

标签: angular

我遇到以下情况,这是行不通的:

1)一种反应形式:

<form [formGroup]="formGroup">  
      <ng-template [doDynamicForm]="field1" [formCtrlName]="indexfield"></ng-template>
</form>

2)doDynamicForm指令,该指令决定要在ng-template中呈现的Component:

    @Directive({   selector: '[doDynamicForm]'})
export class DynamicFormDirective implements OnInit {

  private _field: Field;
  private _formCtrlName: string;

  constructor(private viewContainerRef: ViewContainerRef,
              private resolver: ComponentFactoryResolver) {
  }

  @Input()
  set doDynamicForm(field: Field) {
    this._field = field;
  }

  /**
   * Nome per il from controller
   * @param value
   */
  @Input()
  set formCtrlName(value: string){
   this._formCtrlName = value;
  }

  ngOnInit() {    
    this.generateView();
  }

  private generateView(): void {
    const atype = this.field.datatype;
    switch (atype) {
      case "String":
        const factory = this.resolver.resolveComponentFactory(InputComponent);
        const ref = this.viewContainerRef.createComponent(factory, 0);
        let instance =ref.instance;
        instance.pHolder = this._attribute.name;
        instance.ctrlName = this._ctrlName;
        break;
      case "Date":
        //TODO
        break;
      case "Choice":
        //TODO
        break;
      default:
        throw "Unsupported Attribute type " + atype;
    }
  }
}

我得到的是正确呈现InputComponent中设计的输入文本字段,但是输入字段上的事件没有传播到外部表单。

如果我省略指令并直接使用InputComponent,那么一切都很好。

InputComponent是这样的:

const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => InputComponent),
  multi: true
};

@Component({
  selector: 'wrap-input',
  templateUrl: './input.component.html',
  styleUrls: ['./input.component.scss'],
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR],

})
export class InputComponent implements OnInit, OnDestroy, ControlValueAccessor {
  @Input() pHolder: string;
  @Input() ctrlName: string;
  @Input() intype = 'text';

  control: FormControl = new FormControl('');

  private subscription?: Subscription;
  private onChange: (_: any) => void = (_: any) => {};

  ngOnInit(): void {
    this.subscription = this.control.valueChanges.subscribe(v => {
      this.onChange(v);
    });
  }

  ngOnDestroy(): void {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }

  writeValue(val: any): void {
    this.control.setValue(val, { emitEvent: false });
  }

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

  registerOnTouched(fn: any): void {}

有什么主意吗?

谢谢!

0 个答案:

没有答案