DynamicComponentLoader has been deprecated. I am trying to build a parent component that renders child components inside of the parent component based on an array of child components, meaning that each user has a settings file that holds the child components that need to be in the parent. Right now the parent looks something like this:
import { Component, OnInit, Input, ComponentResolver, ViewContainerRef } from '@angular/core';
import { Child1Component } from '../children/child1.component'
import { Child2Component } from '../children/child2.component'
import { Child3Component } from '../children/child3.component'
import { ParentService } from './parent.service'
@Component({
selector: 'parent',
directives: [Child1Component, Child2Component, Child3Component],
providers: [ParentService],
template: `
<style>
.parent{
background-image: linear-gradient(141deg, #8ecb45 0%, #97cd76 71%, #96d885 100%);
width: 100%;
height: 200px;
}
</style>
<div class="parent"></div>
`
})
export class ParentComponent {
constructor(private parentService:ParentService, private children: any, viewContainer: ViewContainerRef, private componentResolver: ComponentResolver) {
this.children = parentService.getChildren();
for(var i = 0; i < children.length; i++) {
this.componentResolver.resolveComponent(children[i].component)
.then(componentFactory => {
const ctxInjector = viewContainer.injector;
return viewContainer.createComponent(componentFactory, 0, ctxInjector);
})
}
}
}
Right now, call the service in the ParentComponent constructor seems to be causing some issues. But before I was working on looping over the componentResolver, I was able to attach a component underneath then parent node, but not within it.
Does anyone know a better way to build a dynamic parent component? This is to manage a dashboard type of a layout. Most examples are explicit about how many components will be loaded. This wont work for me. I have seen a few posts about how to make this work, but so far I have not seen anything running on with the RC with a config file.
This comes closest to what I am trying to do: http://plnkr.co/edit/jAmMZKz2VqponmFtPpes?p=preview but it uses the dcl...
Currently I am getting an error that I have not figured out when launching the app: TypeError: Cannot read property 'query' of null
Thanks for the help!
Here is a link if you feel like downloading it and giving it a stab:
https://github.com/weswhite/ng2-layout
EDIT/UPDATE: It may have to do with the children: any I am injecting. I dont think I am doing that correctly, still figuring that bit out...
You can use ComponentResolver with a child ViewContainerRef to create the component dynamically and load them in the parent component.
@Component({
selector: 'parent',
providers: [ParentService],
template: `
<style>
.parent{
background-image: linear-gradient(141deg, #8ecb45 0%, #97cd76 71%, #96d885 100%);
width: 100%;
height: 200px;
}
</style>
<div #content></div>
`
})
export class ParentComponent {
@ViewChild('content', { read: ViewContainerRef }) contentContainer: ViewContainerRef;
children: Component[];
constructor(
private parentService:ParentService,
private resolver: ComponentResolver) {
this.children = parentService.getChildren();
}
ngOnInit() {
this.children.forEach( (component, index) => this.loadComponent(component, index));
}
private loadComponent(component: Component, index: number) {
return this
.resolver
.resolveComponent(component)
.then( factory =>
this.contentContainer.createComponent(factory, index, this.contentContainer.injector))
}
}
I also upgraded the provided plunker to use latest @angular and the ComponentResolver instead of the DynamicComponentLoader: Plunker: http://plnkr.co/edit/Z6bXwBcwAnf4DSpNlU8H?p=preview
Using DCL with loadNextTolocation: http://plnkr.co/edit/NYgJzz9UjrtGsNnO5WXS?p=info
P.S: You were getting TypeError: Cannot read property 'query' of null, because of the way you were injecting children
, you have to specify an injectable Type.
See also Angular 2 dynamic tabs with user-click chosen components