Angular 2: how to render a dynamically created component after adding to the DOM

For starters, all of the code is available in Plunker .

Some code

I have an Angular2 root component, for example:

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 add at runtime. These components are also dynamic, created as follows:

 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 .

Description of the problem

I want to create different views of MyDynamicComponent , add them somewhere to the [data-dynamic-content] element tree and make them fully functional.

What i tried

The only thing that has worked so far is a reboot of the newly created component when added 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 DynamicComponentLoader . It seems that this does not meet my needs - the DynamicComponentLoader.loadNextToLocation parameter requires the ViewContainerRef parameter (for example, you must know in advance where your component will be located), and I do not have it. As I mentioned earlier, MyDynamicComponent can be displayed anywhere in the [data-dynamic-content] element tree, not necessarily in this element.

Conclusion

While this works, I seriously doubt that this approach will be scalable (tested in Chrome with more than 1000 complex components - memory consumption reached a maximum of about 750 MB, and then reduced to ~ 400 MB).

Is there a better way to do this than calling bootstrap over and over?

+5
source share

All Articles