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

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

问题描述:

我已经构建了一个名为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的按钮和我可以通过button.parent识别的MessageComponent的按钮。但是我得到了MessageComponent的2个按钮。

当我在CoreButtonService中保存发送的父项并将其记录为按钮时,我得到期望的值:MessageComponent的'MessageForm'和UserComponent的'UserForm'。但button.parent的值都是一样的。这怎么可能?

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

UPDATE

这是plunkr的基本概念。

+0

在MessageComponent上单击UserComponent,显示Object {key:“back”,parent:“MessageForm”},测试并显示“Object {key:”back“,parent:”UserForm“}。什么出错? – Val

+0

@Val这很奇怪。当我第一次点击UserComponent上的“back”时,它会显示Object {key:“back”,parent:“UserForm”}。当我导航到MessageComponent并单击“返回”时,它显示Object {key:“back”,parent:“MessageForm”} Object {key:“back”,parent:“MessageForm”}。所以它被记录了两次。 – user289520

+0

是否有像@Val一样的日志行为的其他访问者?如果是的话,在我的情况下会导致这种行为? – user289520

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

ngOnDestroy() { 
    this.subscription.unsubscribe; 
} 

而不是unsubscribe()。所以这些事件有点疯狂。但无论如何感谢您的帮助。

+0

很忙,很难用手机回复。你的答案很好。 – Val

+0

'this.subscription.unsubscribe()'。 'this.subscription.unsubscribe'是一个noop。 – estus

为了更详细地解释@ user289520的溶液:

  • Subscriptions:表示一个一次性资源,如可观察的执行。订阅有一个重要的方法,即unsubscribe,它不采用任何参数,只处理预订所持有的资源。

您可以在ngOnDestroy()中立即收集想要unsubscribe的订阅。

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

但是除了this.subscription.unsubscribe;你也可以做到这一点,如下所示foreach循环:

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

为什么你不能忘记unsubscribe()angular.js

  • 承诺是渴望并立即执行。观察对象并不急切,只有在执行subscribed时才会执行。
  • 承诺是asynchronous。可观测量可以是synchronousasynchronous
  • 承诺预期只会返回一个值(如函数)。可观测量可以返回零,一个或多个(无限)值。