Reputation: 404
Using Angular 2.0 (final), how can I load a Component
inside of a DOM element created by a non-Angular library, after app bootstrapping and Component rendering has occurred?
I had previously used
DynamicComponentLoader.loadNextToLocation()
to load Components inside of DOM elements, but that was deprecated as of RC5.
The Problem (TL;DR)
I'm attempting to use Angular 2.0 to insert a dynamically-created Component inside of a popup window that is generated at runtime by an external, non-Angular library (specifically, an InfoWindow/Popup
for an ESRI ArcGIS JavaScript API 3.x
Map).
Since the popup window is generated entirely by the external library after app bootstrap
and the parent Component's ngAfterViewInit()/ngAfterContentInit()
events occur, any #ref
tag present in the newly-added popup's DOM is ignored. And without a #ref
tag and the derived ViewContainerRef
, I can't figure out how to insert new Components inside of the popup.
I'm using the same setup shown in this SO answer, namely:
@ViewChild('dynamicContentPlaceHolder', {read: ViewContainerRef})
protected dynamicComponentTarget: ViewContainerRef;
// this will be reference to dynamic content - to be able to destroy it
protected componentRef: ComponentRef<IHaveDynamicData>;
this.compiler
.compileComponentAsync<IHaveDynamicData>(dynamicType, MyModule)
.then((factory: ng.ComponentFactory<IHaveDynamicData>) =>
{
// our component will be inserted after #dynamicContentPlaceHolder
this.componentRef = this.dynamicComponentTarget.createComponent(factory, 0);
// and here we have access to our dynamic component
let component: IHaveDynamicData = this.componentRef.instance;
component.entity = this.entity;
});
Note: Based on @MarkRajcok's post here, I had the idea to try
ChangeDetectorRef.detectChanges()
to trigger a re-render of the parent Component, with the hope that a#ref
tag in the newly-created popup's DOM would be picked up and compiled. But, likely due to my inexperience with Angular 2.0, I've so far had no luck. Perhaps this a misguided approach all together?
Upvotes: 1
Views: 2712
Reputation: 46
i did this, but it feels like a total hack... it did render the component at the dom element location, though
var me = this;
setTimeout(function(){
var simpleComponent = me.componentFactoryResolver.resolveComponentFactory(SimpleComponent);
me.componentRef = me.dynamicTarget.createComponent(simpleComponent);
var node = document.getElementById("theTest");
node.appendChild(me.componentRef['_hostElement'].nativeElement);
}, 10);
Upvotes: 1