Skip to content

Instantly share code, notes, and snippets.

@l0co
Created March 4, 2020 16:22
Show Gist options
  • Save l0co/9cd90c7ea5f1523b2b13147e849d8377 to your computer and use it in GitHub Desktop.
Save l0co/9cd90c7ea5f1523b2b13147e849d8377 to your computer and use it in GitHub Desktop.

Revisions

  1. l0co created this gist Mar 4, 2020.
    59 changes: 59 additions & 0 deletions custom-component.directive.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    import {ComponentFactoryResolver, ComponentRef, Directive, Type, ViewContainerRef} from '@angular/core';

    /**
    * Allows to embed custom components into views.
    *
    * ## Usage in template
    *
    * ```html
    * <ng-template appCustomComponent></ng-template>
    * ```
    *
    * ## Usage in component
    *
    * ```typescript
    * class MyComponentClass {
    *
    * @ViewChild(CustomComponentDirective, {static: true}) customComponentContainer: CustomComponentDirective;
    *
    * somewhereInCode() {
    * this.customComponentContainer.set(MyComponentClass);
    * }
    *
    * }
    * ```
    *
    * @param C Type of dynamic component
    * @see https://angular.io/guide/dynamic-component-loader
    */
    @Directive({
    selector: '[appCustomComponent]'
    })
    export class CustomComponentDirective<C = any> {

    private _component?: ComponentRef<C>;

    constructor(
    public viewContainerRef: ViewContainerRef,
    private resolver: ComponentFactoryResolver,
    ) { }

    get component(): ComponentRef<C> | undefined {
    return this._component;
    }

    cleanup() {
    if (this._component) {
    this._component.destroy();
    this._component = undefined;
    this.viewContainerRef.clear();
    }
    }

    set(component: Type<C>) {
    this.cleanup();
    let configComponentFactory = this.resolver.resolveComponentFactory<C>(component);
    this._component = this.viewContainerRef.createComponent(configComponentFactory);
    }

    }