import { Injectable , Injector , ComponentFactoryResolver , EmbeddedViewRef , ApplicationRef } from '@angular/core' ; @ Injectable ( ) export class DomService { private childComponentRef : any ; constructor ( private componentFactoryResolver , private appRef , private injector ) { } public appendComponentTo ( parentSelector , child , childConfig = { inputs : { } , outputs : { } } ) { const childComponentRef = this . componentFactoryResolver . resolveComponentFactory ( child ) . create ( this . injector ) ; this . attachConfig ( childComponentRef , childConfig ) ; this . childComponentRef = childComponentRef ; this . appRef . attachView ( childComponentRef . hostView ) ; const childDomElem = ( childComponentRef . hostView as EmbeddedViewRef < any > ) . rootNodes [ 0 ] as HTMLElement ; const parentEl = document . querySelector ( parentSelector ) ; if ( parentEl ) parentEl . appendChild ( childDomElem ) ; } public removeComponent ( ) { this . appRef . detachView ( this . childComponentRef . hostView ) ; this . childComponentRef . destroy ( ) ; } private attachConfig ( componentRef , { inputs , outputs } ) { const props = [ ... Object . entries ( outputs ) , ... Object . entries ( inputs ) ] ; props . forEach ( ( [ key , val ] ) => { componentRef . instance [ key ] = val ; } ) ; } } export interface ChildConfig { inputs : { [ input ] : any ; } ; outputs : { [ output ] : any ; } ; }