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 DynamicPanelDirective
s 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 DynamicPanelDirective
s.
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