bixi
Version:
企业级中后台前端解决方案
102 lines (91 loc) • 3.49 kB
text/typescript
import { Directive, EmbeddedViewRef, Input, OnChanges, SimpleChange, SimpleChanges, TemplateRef, ViewContainerRef } from '@angular/core';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
export class BixiLayoutContentDirective { }
export class BixiLayoutHeaderDirective { }
export class BixiLayoutMenuDirective { }
export class NzBixiTemplateOutletDirective implements OnChanges {
private embeddedViewRef: EmbeddedViewRef<NzSafeAny> | null = null;
nzBixiTemplateOutletContext: NzSafeAny | null = null;
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();
}
}
}