UNPKG

bixi

Version:

企业级中后台前端解决方案

102 lines (91 loc) 3.49 kB
import { Directive, EmbeddedViewRef, Input, OnChanges, SimpleChange, SimpleChanges, TemplateRef, ViewContainerRef } from '@angular/core'; import { NzSafeAny } from 'ng-zorro-antd/core/types'; @Directive({ selector: 'bixi-layout-content, [bixi-layout-content]', exportAs: 'bixiLayoutContent', host: { class: 'bixi-layout-content' } }) export class BixiLayoutContentDirective { } @Directive({ selector: 'bixi-layout-header, [bixi-layout-header]', exportAs: 'bixiLayoutHeader', host: { class: 'bixi-layout-header' } }) export class BixiLayoutHeaderDirective { } @Directive({ selector: 'bixi-layout-menu, [bixi-layout-menu]', exportAs: 'bixiLayoutMenu', host: { class: 'bixi-layout-menu' } }) export class BixiLayoutMenuDirective { } @Directive({ selector: '[nzBixiTemplateOutlet]', exportAs: 'nzBixiTemplateOutlet' }) export class NzBixiTemplateOutletDirective implements OnChanges { private embeddedViewRef: EmbeddedViewRef<NzSafeAny> | null = null; @Input() nzBixiTemplateOutletContext: NzSafeAny | null = null; @Input() nzBixiTemplateOutlet: string | TemplateRef<NzSafeAny> | null = null; private recreateView(): void { this.viewContainer.clear(); const isTemplateRef = this.nzBixiTemplateOutlet instanceof TemplateRef; const templateRef = (isTemplateRef ? this.nzBixiTemplateOutlet : this.templateRef) as NzSafeAny; this.embeddedViewRef = this.viewContainer.createEmbeddedView(templateRef, this.nzBixiTemplateOutletContext); } private updateContext(): void { const newCtx = this.nzBixiTemplateOutletContext; let oldCtx = []; if (this.embeddedViewRef) { oldCtx = this.embeddedViewRef.context as NzSafeAny; } if (newCtx) { for (const propName of Object.keys(newCtx)) { oldCtx[propName] = newCtx[propName]; } } } constructor(private viewContainer: ViewContainerRef, private templateRef: TemplateRef<NzSafeAny>) { } ngOnChanges(changes: SimpleChanges): void { const shouldRecreateView = (ctxChanges: SimpleChanges): boolean => { const { nzBixiTemplateOutletContext, nzBixiTemplateOutlet } = ctxChanges; let shouldOutletRecreate = false; if (nzBixiTemplateOutlet) { if (nzBixiTemplateOutlet.firstChange) { shouldOutletRecreate = true; } else { const isPreviousOutletTemplate = nzBixiTemplateOutlet.previousValue instanceof TemplateRef; const isCurrentOutletTemplate = nzBixiTemplateOutlet.currentValue instanceof TemplateRef; shouldOutletRecreate = isPreviousOutletTemplate || isCurrentOutletTemplate; } } const hasContextShapeChanged = (ctxChange: SimpleChange): boolean => { const prevCtxKeys = Object.keys(ctxChange.previousValue || {}); const currCtxKeys = Object.keys(ctxChange.currentValue || {}); if (prevCtxKeys.length === currCtxKeys.length) { for (const propName of currCtxKeys) { if (prevCtxKeys.indexOf(propName) === -1) { return true; } } return false; } else { return true; } }; const shouldContextRecreate = nzBixiTemplateOutletContext && hasContextShapeChanged(nzBixiTemplateOutletContext); return shouldContextRecreate || shouldOutletRecreate; }; const recreateView = shouldRecreateView(changes); if (recreateView) { this.recreateView(); } else { this.updateContext(); } } }