import { ApplicationRef, ComponentFactoryResolver, ComponentRef, EmbeddedViewRef, Injectable, Injector, OnChanges, SimpleChange, SimpleChanges, Type } from '@angular/core' @Injectable() export class DynamicElementService { constructor ( private injector: Injector, private applicationRef: ApplicationRef, private componentFactoryResolver: ComponentFactoryResolver ) { } createElement (ofComponent: Type) { const div = document.createElement('div') const component = this.componentFactoryResolver.resolveComponentFactory(ofComponent) .create(this.injector, [], div) return component } injectElement (wrapper: HTMLElement, componentRef: ComponentRef) { const hostView = componentRef.hostView as EmbeddedViewRef this.applicationRef.attachView(hostView) wrapper.appendChild(hostView.rootNodes[0]) } setModel (componentRef: ComponentRef, attributes: Partial) { const changes: SimpleChanges = {} for (const key of Object.keys(attributes)) { const previousValue = componentRef.instance[key] const newValue = attributes[key] componentRef.instance[key] = newValue changes[key] = new SimpleChange(previousValue, newValue, previousValue === undefined) } const component = componentRef.instance if (typeof (component as unknown as OnChanges).ngOnChanges === 'function') { (component as unknown as OnChanges).ngOnChanges(changes) } componentRef.changeDetectorRef.detectChanges() } }