在扩展类的构造函数中进行订阅无法正常工作

时间:2017-05-30 09:57:00

标签: angular typescript observable subject

我已经构建了一个名为CoreButtonService的抽象类,每个ButtonService都会扩展。例如,有UserButtonService,MessageButtonService等。这些服务将被注入相应的组件,如UserComponent,MessageComponent等。在CoreButtonService的构造函数中,我订阅了另一个名为ButtonsService的服务,该服务负责在单击ButtonModule中的任何按钮时触发事件。

CoreButtonService:

export abstract class CoreButtonService<T extends CoreModel> extends CoreService {

    private backSource = new Subject<string>();
    private submitSource = new Subject<string>();
    back$ = this.backSource.asObservable();
    submit$ = this.submitSource.asObservable();

    constructor(
        private coreButtonsService: ButtonsService,
        private coreLanguageService: LanguageService,
        private coreLocation: Location) {
        super(coreLanguageService);
        this.coreButtonsService
            .buttonClicked$
            .subscribe(button => console.log(button)); // !!!!!!
    }

    // Buttons are going to be built down here ...

}

ButtonsService:

@Injectable()
export class ButtonsService {
    private button = new Subject<ButtonBase<any>>();
    buttonClicked$ = this.button.asObservable();
    constructor(private formService: FormService) { }

    clickButton(button: ButtonBase<any>): void {
        if (button.controlType === 'submit')
            this.formService.submitForm(button.parent);
        this.button.next(button);
    }
}

假设我访问包含UserComponent的页面,单击一个按钮,然后在MessageComponent的页面上执行相同的操作。从技术上讲,控制台中应该记录2个按钮。 UserComponent的按钮和MessageComponent的按钮,我可以通过button.parent识别。但我得到了MessageComponent的2个按钮。

当我在CoreButtonService中保存已发送的父级并将其记录为按钮时,我得到了预期的值:&#39; MessageForm&#39;对于MessageComponent和&#39; UserForm&#39;对于UserComponent。但button.parent的值都是相同的。怎么可能?

我没有看到问题所在。可能是因为每个ButtonService都在CoreButtonService中进行相同的订阅,这就是为什么每个订阅/按钮彼此相关的原因?

更新

这是具有基本概念的plunkr

2 个答案:

答案 0 :(得分:1)

我终于找到了错误,这是一个非常愚蠢的错误。在CoreComponent中,我取消订阅了

ngOnDestroy() {
    this.subscription.unsubscribe;
}

而不是unsubscribe()。事件变得有点疯狂。但无论如何,谢谢你的帮助。

答案 1 :(得分:0)

更详细地解释@ user289520的解决方案:

  • Subscriptions:表示可支配资源,例如执行Observable。订阅有一个重要的方法unsubscribe,它不带参数,只是处理订阅所持有的资源。

您可以在unsubscribe中一次性收集您想要ngOnDestroy()的订阅。

  • ngOnDestroy():在Angular破坏指令/组件之前进行清理。取消订阅observable并分离事件处理程序以避免内存泄漏。

然而,除了this.subscription.unsubscribe;之外,您还可以在foreach循环中执行此操作,如下所示:

this.subscriptions.forEach(s => s.unsubscribe());

为什么不要忘记unsubscribe()中的angular.js

  • 承诺是渴望并立即执行。 Observable并不急切,仅在subscribed to。
  • 时执行
  • 承诺是asynchronous。可观察量可以是synchronousasynchronous
  • Promise预计只返回一个值(如函数)。 Observable可以返回零,一个或多个(无限)值。