Reputation: 1221
I have a new Angular app (can use v 2.4.10 or 4.0.0-rc.5), which uses an iframe to embed some pre-existing content. Using a method called when the iframe loads -- (load)="processIframe(extFrame)"
-- I'm able to set up listeners via the Angular Renderer, and to grab references to child DOM elements (this answer helped with that process).
It's easy enough to set the content of an element in the iframe by replacing its innerHtml
. However, what I need to do is the replace this html with a compiled Angular component. This component grabs some data from an API via a service.
Is there a way to replace DOM element content in the iframe with the compiled component?
Upvotes: 4
Views: 12345
Reputation: 214047
You can create ComponentRef
instance and then insert its compRef.location.nativeElement
in desired place.
I would do it as follows Plunker Example:
@Component({
selector: 'my-app',
template: `
<button (click)="createComponent()">Create component</button>
<iframe #iframe (load)="onLoad()"></iframe>
`,
})
export class App implements AfterViewInit, OnDestroy {
@ViewChild('iframe') iframe: ElementRef;
doc: any;
compRef: ComponentRef<DynamicComponent>;
constructor(
private vcRef: ViewContainerRef,
private resolver: ComponentFactoryResolver) {}
createComponent() {
const compFactory = this.resolver.resolveComponentFactory(DynamicComponent);
this.compRef = this.vcRef.createComponent(compFactory);
this.doc.body.appendChild(this.compRef.location.nativeElement);
}
onLoad() {
this.doc = this.iframe.nativeElement.contentDocument ||
this.iframe.nativeElement.contentWindow;
}
ngAfterViewInit() {
this.onLoad(); // in Firefox state is uninitialized while
// in Chrome is complete so i use `load` event for Firefox
}
ngOnDestroy() {
if(this.compRef) {
this.compRef.destroy();
}
}
}
Don't forget to add DynamicComponent
to `entryComponents array
Upvotes: 17