【问题标题】:Angular 2: "Global" lifecycle hooks?Angular 2:“全局”生命周期钩子?
【发布时间】:2017-01-18 02:47:17
【问题描述】:

TL;DR

我们正在使用 Angular 2 构建一个应用程序,并希望注册一个“全局”ngOnInit 和 ngOnDestroy 函数。对于“全局”,我的意思是为每个组件执行该功能,而无需为每个组件显式实现。这可能吗?

详细

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

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

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

  • 首先,我需要一遍又一遍地实现整个逻辑。是的,我知道,我可以将“样板”代码放在帮助类或其他东西中。但它似乎有点隐含,“隐藏”在常规的 Angular 生命周期中。有一个说话的名字(例如接口/基类)似乎更明确。
  • 其次,所有类都需要扩展相同的通用基类。但是如果他们也应该扩展一些其他的基类(多重继承)呢?

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

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

我的问题

  • Angular 2 可以做到这一点吗? IE。可以注册“全局生命周期钩子”(或类似的东西)吗?
  • 或者这是一个完全错误的方法?
  • 还有其他/更好的想法吗?

【问题讨论】:

    标签: angular


    【解决方案1】:

    强制整个应用程序的行为不是一个好主意,这对初学者来说也会影响第三方组件。

    样板代码可以移动到具体的基类中。有 JS/TS 多重继承的解决方案,例如@mixin,另见TypeScript guide。

    由于基类方法是固定的,类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;
      }
    }
    

    它可以像这样使用

    @Component({ ... })
    @Lifecycled()
    class SomeComponent { .... }
    

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

    【讨论】:

    • 我们可以使用 this 覆盖所有 Angular 的生命周期钩子吗?
    • 是的,我们可以覆盖任何原型方法。
    猜你喜欢
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 2017-11-22
    • 2018-08-30
    • 2018-01-11
    • 2019-06-26
    • 1970-01-01
    相关资源
    最近更新 更多