angular2 / rxjs ngUnsubscribe:如何使用装饰器取消订阅所有订阅?

时间:2017-04-18 17:53:36

标签: angular rxjs angular-decorator

基于edit3 here我实施了该解决方案。但是做主题初始化和"清理"在每个组件的ngOnDestroy中仍然很痛苦。我认为它可以传递给装饰者,例如。基于此post

export function AutoUnsubscribe( constructor ) {

  const original = constructor.prototype.ngOnDestroy;
  constructor.prototype.ngUnsubscribe = new Subject<void>();

  constructor.prototype.ngOnDestroy = function () {
    constructor.prototype.ngUnsubscribe.next();
    constructor.prototype.ngUnsubscribe.complete();
    original && typeof original === "function" && original.apply(this, arguments);
  };

}

用法就像任何其他类装饰器一样。它运行良好,但我在使用它时必须破解类型系统,如下所示:takeUntil((this as any).ngUnsubscribe)

属性ngUnsubscribe无法被组件中的类型系统识别。有没有办法告诉类型系统这个属性是否存在?

如果可以,那么使用这个@AutoUnsubscribe装饰器将非常容易:只需装饰一个类并在每次订阅之前放置takeUntil(this.ngUnsubscribe)。不知道我们是否可以更好地装饰一个类,并且在每次订阅之前,这个装饰者会自动放置takeUntil(this.ngUnsubscribe)。

我目前的解决方法是将BaseComponent与ngUnsubscribe prop一起使用。并扩展调用subscribe的每个组件。

1 个答案:

答案 0 :(得分:0)

也许我会使用太多的模型示例,但我认为有两种方法可以做到这一点:

  • 创建一个只告诉编译器有关类属性的接口

  • 扩展与您的文件名匹配的模块,并将该属性添加到界面

<强> 1。创建一个界面

export interface MyOtherClass {
  magicProperty: string;
}

export class MyOtherClass
{
  func(): void {
    console.log(this.magicProperty);
  }
}

<强> 2。扩展模块

// 43479078.ts
export class MyOtherClass
{
  func(): void {
    console.log(this.magicProperty);
  }
}

...和

// MyOtherClass-extension.d.ts
import { MyOtherClass } from './43479078';

declare module './43479078' {
  interface MyOtherClass {
    magicProperty: void;
  }
}

请注意,现在在编译时,您需要包含这两个文件或在/// <reference path="./MyOtherClass-extension.d.ts" />的顶部添加43479078.ts

另外,我认为需要导出扩展类,否则该文件不会被视为模块。