Aaron Jessen
Aaron Jessen

Reputation: 404

Loading Angular 2 Component in a DOM element created after rendering

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.

The Code

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

Answers (1)

Marc Gusmano
Marc Gusmano

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

Related Questions