My goal is to dynamically generate components based on the configuration options, specifically creating a toolbar with different "toolbar items".
Following the Angular guide at: https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html, I have implemented a dedicated directive:
@Directive({
selector: '[mte-toolbar-item-host]'
})
export class ToolbarItemDirective {
constructor(public viewContainerRef: ViewContainerRef) {
}
}
This directive will serve as the insertion point for the components.
I also created the main ToolbarComponent
:
@Component({
selector: "mte-toolbar",
templateUrl: "./toolbar.component.html",
styleUrls: ["./toolbar.component.css"],
providers: [ToolbarService]
})
export class ToolbarComponent implements AfterViewInit {
toolbar: Toolbar;
@ViewChild(ToolbarItemDirective)
toolbarItemHost: ToolbarItemDirective;
constructor(private toolbarService: ToolbarService, private componentFactoryResolver: ComponentFactoryResolver) {
}
ngAfterViewInit(): void {
this.toolbar = new Toolbar(this.toolbarService.getToolbarItems());
for (let i in this.toolbar.items) {
let toolbarItem = this.toolbar.items[i];
let toolbarItemFactory = this.componentFactoryResolver.resolveComponentFactory(toolbarItem.componentType);
let componentRef = this.toolbarItemHost.viewContainerRef.createComponent(toolbarItemFactory);
componentRef.instance.toolbarItem = toolbarItem;
}
}
}
The template for the ToolbarComponent
includes an unordered list with injection points:
<ul class="nav nav-pills">
<li role="presentation" mte-toolbar-item-host></li>
</ul>
The toolbarService
currently provides a list of default components:
...
GlyphToolbarItem
and GlyphToolbarItemComponent
classes were implemented to handle the toolbar items and their templates respectively. Here's how they are structured:
...
I anticipated the output to be rendered correctly within list elements, but instead, the dynamic components are wrapped in <div>
. Is this behavior correct or is there a better way to achieve this?