角度2:“全局"生命周期挂钩? [英] Angular 2: "Global" lifecycle hooks?
问题描述
TL; DR
我们正在使用Angular 2构建一个应用程序,并希望注册一个全局" ngOnInit
和ngOnDestroy
函数. 全局"是指对每个组件都执行该功能,而无需为每个组件显式实现.这可能吗?
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?
详细
我们的某些(但不是全部)组件需要在加载后在全局服务中注册某些内容(例如ngOnInit
),并在卸载后再次注销(例如ngOnDestroy
).我可以想到以下两种方法:
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
和ngOnDestroy
中)实施此逻辑. - 在基类中实现此逻辑,该基类调用由子类实现的抽象方法,这些子类指定哪些内容需要注册/取消注册.
- Implement this logic in every component which needs to do so (in
ngOnInit
andngOnDestroy
). - Implement this logic in a base class which calls abstract methods implemented by the sub classes which specify, what needs to be registered/unregistered.
两种方法都不能令人满意:
Both approaches aren't really satisfying:
- 首先,我需要一遍又一遍地实现整个逻辑.是的,我知道,我可以将样板"代码放在助手类之类的东西中.但是,在常规的Angular生命周期中,它似乎有点隐藏".拥有语音名称(例如接口/基类)似乎更加明确. 第二,所有类都需要扩展相同的公共基类.但是,如果他们还应该扩展其他一些基类(多重继承)怎么办?
- In the first I need to implement the whole logic over and over again. Yeah, I know, I could put the "boiler plate"-code in a helper class or something. But it seems to be slightly implicit, "hidden" in the regular Angular lifecycle. Having a speaking name (e.g. interface/base class) seems more explicit.
- In the second all classes need to extend the same, common base class. But what if they should also extend some other base class (multiple inheritance)?
这就是为什么我想到了以下想法:
That's why i came up with following idea:
为什么不将上述抽象类替换为可以由所有必需组件实现的接口.然后我将注册一个全局函数,该函数在所有组件的每个ngOnInit
和ngOnDestroy
上执行(如果可能-例如在模块,路由等中?).在该函数中,我将检查组件是否实现了接口,以及是否实现了接口,然后调用适当的函数以获取要注册的类型特定的东西.
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.
我的问题
- Angular 2可以这样做吗? IE.可以注册全局生命周期挂钩"(或类似的东西)吗?
- 还是这是完全错误的方法?
- 还有其他/更好的主意吗?
推荐答案
强制整个应用程序运行不是一个好主意,这也会影响初学者的第三方组件.
Forcing the behaviour for the entire app wouldn't be a good idea, this affects third-party components as well for starters.
样板代码可以移到具体的基类中.有JS/TS多重继承的解决方案,例如 @mixin ,另请参见
Boilerplate code can be moved into concrete base class. There are solutions for JS/TS multiple inheritance, e.g. @mixin, see also TypeScript guide.
由于基类方法是固定的,因此类mixin可以表示为简化的装饰器:
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;
}
}
它可以像
@Component({ ... })
@Lifecycled()
class SomeComponent { .... }
实现仅限于ngOnInit
等.原型方法,箭头成员需要对构造函数进行修补.
The implementation is limited to ngOnInit
, etc. prototype methods, arrow members require a constructor to be patched.
这篇关于角度2:“全局"生命周期挂钩?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!