All files / ngui-utils/src dynamic-component.service.ts

100% Statements 13/13
50% Branches 1/2
100% Functions 3/3
100% Lines 11/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 744x                                                                       4x             20x                   1x 1x   1x             1x 1x 1x   1x   1x        
import {
  Component,
  ComponentFactoryResolver,
  ComponentRef,
  Inject,
  Injectable,
  ViewContainerRef
} from '@angular/core';
 
/**
 * Insert a component dynamically using a service
 *
 
 ### Example
 ```ts
 import { DynamicComponentService } from './dynamic.component.service';
 import { MyDynamicComponent } from './my-1.component';
 
 @Component({
   template: ` ... <div #dymamic></div>`
 })
 export class MyComponent {
   @ViewChild('dynamic', {read:ViewContainerRef}) vcr: ViewContainerRef;
 
   constructor(public dcs: DynamicComponentService) {}
 
   insertComp() {
     let compRef = this.dcs.createComponent(MyDynamicComponent, this.vcr);
     ths.dcs.insertComonent(cmpRef);
     compRef.instance.items = [1,2,3];              // dealing with @input
     compRef.instance.output$.subscribe(val => {}); // dealing with @output
   }
 }
 ```
 */
@Injectable()
export class DynamicComponentService {
  /** used to create a factory from a component class */
  factoryResolver: ComponentFactoryResolver;
  /** defines where a dynamic components insert into */
  rootViewContainer: ViewContainerRef;
 
  constructor(@Inject(ComponentFactoryResolver) factoryResolver) {
    this.factoryResolver = factoryResolver;
  }
 
  /**
   * returns component reference
   * The reason to seperate `createCompnent` and `insertComponent` is
   * to allow some actions before we insert into a hostView.
   * e.g styling, setting attributes, etc
   */
  createComponent(component: any, into?: ViewContainerRef): ComponentRef<any> {
    this.rootViewContainer = into || this.rootViewContainer;
    const factory = this.factoryResolver.resolveComponentFactory(component);
 
    return factory.create(this.rootViewContainer.parentInjector);
  }
 
  /**
   * insert component
   */
  insertComponent(componentRef: ComponentRef<any>): Component {
    const compId = `ngui-dyn-${Math.floor(Math.random() * 10 ** 7) + 10 ** 6}`;
    componentRef.location.nativeElement.setAttribute('id', compId);
    componentRef.instance.id = compId;
 
    this.rootViewContainer.insert(componentRef.hostView);
 
    return componentRef.instance;
  }
 
}