TL;DR
We are building an app with Angular 2 and would like to register a "global" ngOnInit
and ngOnDestroy
function. With "global" I mean that the function is executed for every component, without needing to be explicitly implemented for every component. Is this possible?
Detailed
Some (but not all) of our components need to register something in a global service once they are loaded (e.g. ngOnInit
) and unregister it again, once they are unloaded (e.g. ngOnDestroy
). Here are two approaches I can think of:
ngOnInit
and ngOnDestroy
).Both approaches aren't really satisfying:
That's why i came up with following idea:
Why not replace the above mentioned abstract class with an interface that can be implemented by all the required components. I would then register a global function which is executed on every ngOnInit
and ngOnDestroy
of all the components (if possible - e.g. in an module, routing, etc.?). In the function I would check if the component implements the interface and if it does, then call the appropriate function to get the type specific stuff to be registered.
My questions
Forcing the behaviour for the entire app wouldn't be a good idea, this affects third-party components as well for starters.
Boilerplate code can be moved into concrete base class. There are solutions for JS/TS multiple inheritance, e.g. @mixin, see also TypeScript guide.
Since base class methods are fixed, class mixin can be expressed as a simplified decorator:
class CustomLifecycle implements OnInit, OnDestroy {
constructor(
public originalNgOnInit: Function,
public originalNgOnDestroy: Function
) {}
ngOnInit() {
...
if (typeof this.originalNgOnInit === 'function') {
this.originalNgOnInit();
}
}
ngOnDestroy() {
...
if (typeof this.originalNgOnDestroy === 'function') {
this.originalNgOnDestroy ();
}
}
}
function Lifecycled() {
return function (target: Function) {
const customLifecycle = new CustomLifecycle(
target.prototype.ngOnInit,
target.prototype.ngOnDestroy
);
target.prototype.ngOnInit = customLifecycle.ngOnInit;
target.prototype.ngOnDestroy = customLifecycle.ngOnDestroy;
}
}
And it can be used like
@Component({ ... })
@Lifecycled()
class SomeComponent { .... }
The implementation is limited to ngOnInit
, etc. prototype methods, arrow members require a constructor to be patched.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With