From 31c224c9f9c015e94877d1eba382d1cd415704c7 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Wed, 25 Dec 2019 18:30:01 +0300 Subject: [PATCH] feat(core): add init directive --- ...eplaceable-template-container.component.ts | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 npm/ng-packs/packages/core/src/lib/components/replaceable-template-container.component.ts diff --git a/npm/ng-packs/packages/core/src/lib/components/replaceable-template-container.component.ts b/npm/ng-packs/packages/core/src/lib/components/replaceable-template-container.component.ts new file mode 100644 index 0000000000..bd54cd2ee1 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/components/replaceable-template-container.component.ts @@ -0,0 +1,108 @@ +import { + Component, + EventEmitter, + Inject, + Input, + OnDestroy, + OnInit, + Output, + TemplateRef, + Type, + Attribute, + Renderer2, +} from '@angular/core'; +import { Store } from '@ngxs/store'; +import { distinctUntilChanged, filter } from 'rxjs/operators'; +import { ABP } from '../models/common'; +import { ReplaceableComponents } from '../models/replaceable-components'; +import { ReplaceableComponentsState } from '../states/replaceable-components.state'; +import { takeUntilDestroy } from '../utils/rxjs-utils'; +import compare from 'just-compare'; +import snq from 'snq'; + +@Component({ + selector: 'abp-replaceable-template-container', + template: ` + + + `, + exportAs: 'abpReplaceableTemplateContainer', + providers: [{ provide: 'INPUTS', useValue: {} }], +}) +export class ReplaceableTemplateContainerComponent implements OnInit, OnDestroy { + @Input() + defaultTemplate: TemplateRef; + + @Input() + inputs: ReplaceableComponents.ReplaceableTemplateInput[] = []; + + @Output() + readonly writableInputsChange = new EventEmitter(); + + @Output() + readonly externalComponentInit = new EventEmitter(); + + @Output() + readonly defaultTemplateInit = new EventEmitter(); + + externalComponent: Type = null; // externalComponent must equal to null + + initDefaultTemplate = (ref: any) => { + console.warn(ref); + }; + + constructor( + @Attribute('componentKey') private componentKey: string, + @Inject('INPUTS') public inputsProvider: ABP.Dictionary, + private store: Store, + private renderer: Renderer2, + ) {} + + ngOnInit() { + this.store + .select(ReplaceableComponentsState.getComponent(this.componentKey)) + .pipe( + takeUntilDestroy(this), + filter( + (res = {} as ReplaceableComponents.ReplaceableComponent) => + !compare(this.externalComponent, res.component), + ), + ) + .subscribe(({ component } = {} as ReplaceableComponents.ReplaceableComponent) => { + console.warn('STOREDAN DATA GELDI!!'); + this.externalComponent = component; + if (component) { + this.externalComponentInit.emit(); + } else { + this.defaultTemplateInit.emit(); + } + }); + + this.defineProperties(); + } + + defineProperties() { + const writableInputs = this.inputs + .filter(input => input.writable) + .reduce((acc, val) => ({ ...acc, [val.key]: val.value }), {}); + + this.inputs.forEach((input, index) => { + Object.defineProperty(this.inputsProvider, this.inputs[index].key, { + get: () => this.inputs[index].value, + ...(this.inputs[index].writable && { + set: newValue => { + writableInputs[input.key] = newValue; + this.writableInputsChange.emit(writableInputs); + this.inputs[index] = { ...this.inputs[index], value: newValue }; + }, + }), + enumerable: true, + configurable: true, + }); + }); + } + + ngOnDestroy() {} +}