UNPKG

first-npm-package-nicule

Version:

This isi first npm package

128 lines (105 loc) 4.27 kB
import { ComponentFactory, ComponentFactoryResolver, ComponentRef, Directive, Injector, Input, OnChanges, SimpleChanges, Type, ViewContainerRef } from '@angular/core'; import { NgForm } from '@angular/forms'; import { HypermediaField, LabelingService } from 'first-npm-package-nicule/core'; import { BaseInputComponent } from '../classes'; import { InputComponentResolver } from '../services'; import { HypermediaForm } from '../components'; @Directive({ selector: '[hmInputOf]' }) export class InputDirective implements OnChanges { private componentFactory: ComponentFactory<BaseInputComponent>; private inputSettings: any = {}; private componentRef: ComponentRef<BaseInputComponent>; private isCreated = false; private field: HypermediaField; @Input() set hmInputOfSettings(settings: any) { if (settings) { this.inputSettings = settings; if (this.componentRef && this.componentRef.changeDetectorRef) { this.componentRef.instance.settings = settings; } } } @Input() set hmInputOf(field: HypermediaField) { if (field) { this.field = field; } } constructor(private viewContainer: ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver, private labelingService: LabelingService, private injector: Injector, private hmForm: HypermediaForm, private inputComponentResolver: InputComponentResolver ) { } ngOnChanges(changes: SimpleChanges): void { if ('hmInputOf' in changes) { this.onFieldChange(changes.hmInputOf.previousValue, changes.hmInputOf.currentValue); } } onFieldChange(oldField, newField): void { let componentType: Type<any>; let reRender = false; if (!this.field && !this.isCreated) { return; } if ((!this.isCreated && !this.componentFactory) || oldField.name !== newField.name || oldField.type !== newField.type) { componentType = this.inputComponentResolver.resolve(newField); const newFactory = this.componentFactoryResolver.resolveComponentFactory(componentType); reRender = newFactory !== this.componentFactory; this.componentFactory = newFactory; } if (this.isCreated && reRender) { this.delete(); } if (newField && !this.isCreated) { this.create(); } else if (newField && this.isCreated) { this.update(); } else { this.delete(); } if (newField && !this.isCreated) { this.create(); } else if (newField && this.isCreated) { this.update(); } else { this.delete(); } } delete(): void { this.viewContainer.clear(); this.componentRef.destroy(); delete this.componentRef; this.isCreated = false; } update(): void { this.componentRef.instance.field = this.field; this.componentRef.instance.labelingService = this.labelingService; this.componentRef.instance.settings = { ...this.componentRef.instance.settings, ...this.inputSettings }; this.componentRef.changeDetectorRef.detectChanges(); this.componentRef.instance['onSettingsChanged'](); } create(): void { let injector = this.injector; const parentInjector = this.injector; if (this.hmForm && this.hmForm.ngForm) { injector = { // Force injector to resolve form as the settings form get: (token, notFoundValue): any => { if (token === NgForm) { return this.hmForm.ngForm; } return parentInjector.get(token, notFoundValue); } }; } this.componentRef = this.viewContainer.createComponent(this.componentFactory, 0, injector); this.isCreated = true; this.update(); } }