typescript - Angular 2: hvordan rendre en dynamisk opprettet komponent etter å ha lagt den til i DOM
For å begynne med, er all koden tilgjengelig i Plunker.
Noe kode
Jeg har en rot Angular2-komponent, slik som dette:
import {Component} from '@angular/core'
@Component({
selector: 'my-app',
template: `
<h2>Angular2 Root Component</h2>
<div data-dynamic-content></div>
`,
})
export class App {}
Elementet [data-dynamic-content] er en plassholder for komponenter som jeg vil legge til under kjøring. Disse komponentene er også dynamiske, og opprettes slik:
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;
};
Vennligst husk at dette er et ekstremt forenklet eksempel.
Problemstilling
Jeg vil lage forskjellige representasjoner av MyDynamicComponent, legge dem et sted inn i [data-dynamic-content]-elementtreet, og få dem til å være fullt funksjonelle.
Hva jeg har prøvd
Det eneste som har fungert så langt, er å bootstrappe den nyopprettede komponenten når den legges til i 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);
};
Jeg lekte også med DynamicComponentLoader. Det så ikke ut til å passe mine behov - DynamicComponentLoader.loadNextToLocation krever en ViewContainerRef-parameter (f.eks. du må på forhånd vite hvor komponenten din skal plasseres), og det har jeg ikke. Som jeg nevnte tidligere, kunne MyDynamicComponent bli rendret hvor som helst i [data-dynamic-content]-elementtreet, ikke nødvendigvis i dette elementet selv.
Konklusjon
Selv om dette fungerer, tviler jeg sterkt på at en slik tilnærming vil være skalerbar (testet i Chrome med 1000 mer komplekse komponenter - minneforbruket nådde en topp på rundt 750 MB, for deretter å reduseres til ~ 400 MB).
Finnes det en bedre måte å få dette til å fungere på enn å kalle bootstrap om og om igjen?