Angular 2:"全球"生命周期挂钩?

PzY*_*Yon 3 angular

TL; DR

我们正在使用Angular 2构建一个应用程序,并希望注册一个"全局" ngOnInitngOnDestroy功能.对于"全局",我的意思是该函数是针对每个组件执行的,而不需要为每个组件显式实现.这可能吗?

详细

一些(但不是全部)组件需要在加载(例如ngOnInit)后在全局服务中注册某些内容,并在卸载后再次注销(例如ngOnDestroy).以下是我能想到的两种方法:

  • 在每个需要这样做的组件中实现这个逻辑(in ngOnInitngOnDestroy).
  • 在基类中实现此逻辑,该基类调用由子类实现的抽象方法,这些子类指定需要注册/未注册的内容.

这两种方法都不令人满意:

  • 在第一个我需要一遍又一遍地实现整个逻辑.是的,我知道,我可以将"锅炉板" - 代码放在帮助器类或其他东西中.但它似乎有点隐含,"隐藏"在常规的Angular生命周期中.具有发言名称(例如,接口/基类)似乎更明确.
  • 在第二个类中需要扩展相同的公共基类.但是,如果他们还应该扩展其他一些基类(多重继承)呢?

这就是我提出以下想法的原因:

为什么不用可以由所有必需组件实现的接口替换上面提到的抽象类.然后我会登记其上每执行一个全局函数ngOnInitngOnDestroy所有组件(如果可能的话-例如一个模块,路由等中).在函数中,我将检查组件是否实现了接口,如果是,则调用相应的函数以获取要注册的类型特定的东西.

我的问题

  • Angular 2可以这样做吗?即,可以注册"全球生命周期钩子"(或类似的东西)?
  • 或者这是一个完全错误的方法呢?
  • 还有其他更好的想法吗?

Est*_*ask 7

强制整个应用程序的行为不是一个好主意,这会影响第三方组件以及初学者.

Boilerplate代码可以移动到具体的基类中.有JS/TS多重继承的解决方案,例如@mixin,另请参阅TypeScript指南.

由于基类方法是固定的,因此类mixin可以表示为简化的装饰器:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

它可以像使用一样使用

@Component({ ... })
@Lifecycled()
class SomeComponent { .... }
Run Code Online (Sandbox Code Playgroud)

实现仅限于ngOnInit等原型方法,箭头成员需要修补构造函数.