2017-04-18 91 views
2

基于编辑3 here我实现了该解决方案。但是,在每个组件中进行主题初始化和“清理”ngOnDestroy仍然很痛苦。我认为它可以传递给装饰者,例如。基于此postangular2/rxjs ngUnsubscribe:如何退订所有与装饰订阅?

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道具。并扩展每个调用订阅的组件。

+0

发现这很难:如果在编译时ngOnDestroy在组件上不存在,ng buld --prod --aot会优化掉任何对ngOnDestroy的调用,即使该方法在运行时可用。解决方案:使用@AutoUnsubscribe时始终有一个ngOnDestroy,即使它是空的 –

回答

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的顶部。

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