1

currently the FormGroupDirective.directives reveals only NgControl directive extensions, implemented following this SOF answer of how to attach a FormControlName to a dynamically created component.

export class DynamicPanelDirective extends NgControl implements OnInit  {

  _control: FormControl;

  constructor(
    @Optional() @Host() @SkipSelf() private parent: ControlContainer,
    private resolver: ComponentFactoryResolver,
    private container: ViewContainerRef) {
    super();
  }

  ngOnInit() {
    let component = this.resolver.resolveComponentFactory<GeneralPanelComponent>(GeneralPanelComponent);
    this.name = 'general';
    this.component = this.container.createComponent(component);
    this.valueAccessor = this.component.instance;
    this._control = this.formDirective.addControl(this);
  }
  ...
}

When logging this.parent.formDirective.directives, I get an array of all DynamicPanelDirectives attached to the FormGroupDirective

directives: Array(2)
0: DynamicPanelDirective {_parent: null, name: "input", valueAccessor: InputComponent, _rawValidators: Array(0), _rawAsyncValidators: Array(0), …}
1: DynamicPanelDirective {_parent: null, name: "select", valueAccessor: SelectComponent, _rawValidators: Array(0), _rawAsyncValidators: Array(0), …}

Which is great.

Next step was extending the NgModelGroup to attach the formGroupName to dynamically created groups and thereafter attaching the controls to their hosting groups

I followed the pattern, also aided by this github issue contribution and extended NgModelGroup to another directive - DynamicGroupDirective

export class DynamicGroupDirective extends NgModelGroup implements OnInit, OnDestroy {
  @Input() config: GroupControlConfig;
  component: ComponentRef<any>;

  constructor(
    @Host() @SkipSelf() private parent: ControlContainer,
    @Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
    @Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[],
    private resolver: ComponentFactoryResolver,
    private container: ViewContainerRef
  ) {
    super(parent, validators, asyncValidators);
  }

  ngOnInit(): void {
    this.name = this.config.name;
    const factory = this.resolver.resolveComponentFactory<any>(component);
    component = this.container.createComponent(factory);
  }

  get path(): string[] {
    return [...this.config.breadcrumbs !, this.name];
  }

Now each control is assigned to its proper group host

Problem is, I cannot see any DynamicGroupDirective in the this.parent.formDirective.directives array, only DynamicPanelDirectives.

I noticed that the directives are being appended because of this appending:

// dynamic-panel.directive.ts ~ ngOnInit()
this._control = this.formDirective.addControl(this);

And I understand I have to utilize the matching function in the DynamicGroupDirective, which is

this.parent.formDirective.addFormGroup(this);

But I do not understand what do I need to assign in to, as it is not added to the directives array by itself, and I cannot assign to this.control as it is marked readonly

The usecase is to access the correct DynamicGroupDirective utilising the config.breadcrumbs which help with attaching it to the group, but I also need the dynamic component itself to be rendered inside its proper group ViewContainerRef

SO maybe someone has a better suggestion.. Thank you for anyone who has read up this far

shuk
  • 1,745
  • 1
  • 14
  • 25

0 Answers0