Skip to content

Instantly share code, notes, and snippets.

@FFKL
Last active August 17, 2020 17:56
Show Gist options
  • Select an option

  • Save FFKL/8d0e793c73b74921cac6dd3a17bd8feb to your computer and use it in GitHub Desktop.

Select an option

Save FFKL/8d0e793c73b74921cac6dd3a17bd8feb to your computer and use it in GitHub Desktop.
Page decorator which wrap ngOnDestroy and ngOnInit functions for change global layout structure. Works in Angular 9 + Ivy + AOT.
import { Injector, NgModule, ɵComponentDef as ComponentDef, ɵNG_COMP_DEF } from '@angular/core';
import { LayoutType } from '@constants/layout';
import { GlobalLayoutStore } from '@services/store/global-layout.store';
const NG_COMP_DEF = ɵNG_COMP_DEF as 'ɵcmp';
interface Options {
layout?: LayoutType;
}
type RemoveReadonly<T> = {
-readonly [P in keyof T]: T[P];
};
@NgModule()
export class StaticInjectorModule {
static injector: Injector;
constructor(injector: Injector) {
StaticInjectorModule.injector = injector;
}
}
export function Page({ layout }: Options = {}) {
return function decorator<T extends { new(...args: any[]): any }>(constructor: T) {
const component = getComponentDef(constructor as T & { [NG_COMP_DEF]: ComponentDef<any> });
if (!component) {
throw new Error('Page decorator can be used only for angular components');
}
const { onDestroy, onInit } = component;
component.onDestroy = function () {
onDestroy && onDestroy.call(this);
const { globalLayout } = getServices();
globalLayout.resetLayout();
};
component.onInit = function () {
onInit && onInit.call(this);
const { globalLayout } = getServices();
layout && globalLayout.setLayout(layout);
};
};
}
function getServices() {
return {
globalLayout: StaticInjectorModule.injector.get(GlobalLayoutStore)
};
}
function getComponentDef(constructor: { new(...args: any[]): any, [NG_COMP_DEF]: ComponentDef<any> }): RemoveReadonly<ComponentDef<any>> {
return constructor[NG_COMP_DEF];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment