Skip to content

Instantly share code, notes, and snippets.

@benjamincharity
Created April 28, 2017 14:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benjamincharity/8116414c7f38cffe3cef0e44fe44295d to your computer and use it in GitHub Desktop.
Save benjamincharity/8116414c7f38cffe3cef0e44fe44295d to your computer and use it in GitHub Desktop.
A directive to dynamically compile HTML. Source: https://plnkr.co/edit/mcvILwmOLvrS2PxIrXX8?p=preview
import {
Component,
Directive,
NgModule,
Input,
ViewContainerRef,
Compiler,
ComponentFactory,
ModuleWithComponentFactories,
ComponentRef,
ReflectiveInjector
} from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> {
const cmpClass = class DynamicComponent {};
const decoratedCmp = Component(metadata)(cmpClass);
@NgModule({ imports: [CommonModule, RouterModule], declarations: [decoratedCmp] })
class DynamicHtmlModule { }
return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
.then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => {
return moduleWithComponentFactory.componentFactories
.find(x => x.componentType === decoratedCmp);
});
}
@Directive({
selector: 'client-html-outlet',
})
export class ClientHtmlOutletDirective {
@Input() html: string;
cmpRef: ComponentRef<any>;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) { }
ngOnChanges() {
const html = this.html;
if (!html) return;
if (this.cmpRef) {
this.cmpRef.destroy();
}
const compMetadata = new Component({
selector: 'dynamic-html',
template: this.html,
});
createComponentFactory(this.compiler, compMetadata).then(factory => {
const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
this.cmpRef = this.vcRef.createComponent(factory, 0, injector, []);
});
}
ngOnDestroy() {
if (this.cmpRef) {
this.cmpRef.destroy();
}
}
}
@Oztrea
Copy link

Oztrea commented Sep 23, 2020

I'm trying to use your directive to include a mvc partial view in my angular. But it doesn't work with Angular 10. Any Idea what's wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment