import { ViewContainerRef , ComponentFactoryResolver , ComponentRef , EmbeddedViewRef } from "@angular/core" ; import { FormControlConfig } from '../../services/form-control-config' ; import { DynamicFormBuildConfig } from "../../models/interface/dynamic-form-build-config" ; export interface ComponentType < T > { new ( ... args ) : T ; } export class ComponentView < T > { private component : ComponentType < T > ; private viewContainerRef : ViewContainerRef ; private componentFactoryResolver : ComponentFactoryResolver ; private componentRef : ComponentRef < T > ; constructor ( _component , _viewContainerRef , _componentFactoryResolver , private formControlConfig , private dynamicFormBuildConfig ) { this . component = _component ; this . viewContainerRef = _viewContainerRef ; this . componentFactoryResolver = _componentFactoryResolver ; } create ( ) { let componentFactory = this . componentFactoryResolver . resolveComponentFactory ( this . component ) ; this . componentRef = this . viewContainerRef . createComponent ( componentFactory , this . viewContainerRef . length , this . viewContainerRef . parentInjector ) ; this . setParams ( this . componentRef . instance ) ; } private setParams ( instance ) { if ( this . formControlConfig . inputs ) { let propNames = Object . getOwnPropertyNames ( this . formControlConfig . inputs ) ; for ( let propName of propNames ) this . overridePropAndSetValue ( instance , propName , this . formControlConfig . inputs ) ; } instance [ "controlConfig" ] = this . formControlConfig ; instance [ "dynamicFormBuildConfig" ] = this . dynamicFormBuildConfig ; } overridePropAndSetValue ( instance , propName , inputs ) { let descriptor = Object . getOwnPropertyDescriptor ( Object . getPrototypeOf ( inputs ) , propName ) ; let value = '' ; if ( ! descriptor ) { value = inputs [ propName ] ; delete inputs [ propName ] ; } Object . defineProperty ( inputs , propName , { get ( ) { return ( descriptor ) ? descriptor . get ( ) : value ; } , set ( v ) { instance [ propName ] = v ; ( descriptor ) ? descriptor . set . call ( inputs , v ) : value = v ; } } ) ; instance [ propName ] = descriptor ? descriptor . get . call ( inputs ) : value ; } rootNode ( ) { return ( this . componentRef . hostView as EmbeddedViewRef < any > ) . rootNodes [ 0 ] as HTMLElement ; } getComponentRef ( ) { return this . componentRef ; } destroy ( ) { if ( this . componentRef ) { this . componentRef . destroy ( ) ; this . componentRef = undefined ; } } }