To start with, all the code is available in Plunker.
Some code
I have a root Angular2 component, like this:
import {Component} from '@angular/core'
@Component({
selector: 'my-app',
template: `
<h2>Angular2 Root Component</h2>
<div data-dynamic-content></div>
`,
})
export class App {}
The [data-dynamic-content]
element is a placeholder for components that I will be adding at runtime. These components are dynamic, too, created like this:
import {Component} from '@angular/core'
export function createComponent(selector: string, value: string) {
@Component({
selector: selector,
template: `<h4>Dynamic Component: {{v}}</h4>`,
})
class MyDynamicComponent {
v = value;
}
return MyDynamicComponent;
};
Please, keep in mind, that this is an extremely simplified example.
Problem statement
I want to create different representations of MyDynamicComponent
, append them somewhere into the [data-dynamic-content]
element tree, and have them fully-functional.
What I've tried
The only thing that worked so far is bootstrapping the freshly created component upon appending to the DOM:
import {bootstrap} from '@angular/platform-browser-dynamic';
import {createComponent} from './my-dynamic.component';
export function addComponentDynamically(selector, value) {
var dynamicComponent = createComponent(selector, value);
var container = document.querySelector('[data-dynamic-content]');
var wrapper = document.createElement("div");
wrapper.innerHTML = `<${selector}></${selector}>`;
container.appendChild(wrapper);
// !! won't work without this line
bootstrap(dynamicComponent);
};
I also played with the DynamicComponentLoader
. It didn't look like it will fit my needs - the DynamicComponentLoader.loadNextToLocation
requires a ViewContainerRef
parameter (e.g. you should know beforehand where your component will be located), and I don't have this. As I mentioned before, the MyDynamicComponent
could be rendered anywhere in the [data-dynamic-content]
element tree, not necessarily in this element itself.
Conclusion
While this works, I seriously doubt that such an approach will be scalable (tested in Chrome with 1000 more complex components - memory consumption peaked at around 750 MB, then reduced to ~ 400 MB).
Is there any better way to make this work than calling bootstrap
over and over again?