【问题标题】:BehaviorSubject not working Angular 5BehaviorSubject 不工作 Angular 5
【发布时间】:2018-06-14 23:11:40
【问题描述】:

我似乎无法弄清楚问题是什么,

我的服务具有这样的行为主题...

popupSource = new BehaviorSubject<any>('');

popup(component) {
   this.popupSource.next(component);
}

然后在我的标题组件中

popupClick() {
    this._service.popup('example');    
}

然后在我的 header.html 中

<button (click)="popupClick()"></button>

然后在我的应用组件中

ngOnInit() {
    this._service.popupSource.subscribe((result) => {
       console.log(result);
    })
}

所以发生的事情是点击触发了this._service.popup('example');,但它从未点击订阅...

我在每个函数上都设置了断点,它成功到达this.popupSource.next(component),但是什么也没有??每次单击按钮时,我都应该获得控制台日志。

我不确定我做错了什么...为简洁起见,我省略了代码,所以如果您需要更多信息,请告诉我

编辑

我也试过了

private popupSource = new BehaviorSubject<any>('');

getPopup = this.popupSource.asObservable();

popup(component) {
   this.popupSource.next(component);
}

而我的应用程序组件中的 getPopup 改为监听

ngOnInit() {
    this._service.getPopup.subscribe((result) => {
       console.log(result);
    })
}

这也不起作用,我无法弄清楚问题是什么......

谢谢

【问题讨论】:

  • 你确定你有相同的服务实例吗?你在哪里提供?
  • 我有两个单独的模块,一个主模块和一个应用模块,应用组件在 appModule 中,标题组件在 mainModule 中,但我在两个模块中都提供服务,或者我应该导出它在 appModule 中,然后在 mainModule 中从那里抓取它??
  • 您不应在两个不同的模块中提供。它为每个模块创建一个实例,这就是它不起作用的原因。
  • @GeoAstronaute 那么我应该如何提供它??
  • @GeoAstronaute 我已将其从 mainModule 的提供程序列表中删除,但它仍然无法正常工作..

标签: javascript angular typescript behaviorsubject


【解决方案1】:

您的问题是您在两个不同的模块中提供服务,最终得到您的服务的两个实例。如果您使用 Angular v6,最简单的方法是在您的服务中使用 providedIn 标志:

import { Injectable } from '@angular/core';

@Injectable({providedIn: 'root'})
class myService {}

通过这种方式,您无需在任何模块的 providers 数组中提供服务,它会自动在根注入器中提供。

可以在此处找到有关此的文档:Angular providers

如果您使用的是 Angular v5,您应该只在您的 AppModule 中提供您的服务。

【讨论】:

  • 我正在使用 Angular 5,并且我已将服务从我的 mainModule 中取出,但它似乎仍然无法正常工作
  • 好的,所以我删除了该服务的每个实例并重新设置它,现在它可以工作了,谢谢!
  • 没问题,很高兴为您提供帮助!
  • 主啊!另外,不能放在其他模块的 providers[] 中。
【解决方案2】:

在你的服务中,写一个这样的新方法:

popupSource = new BehaviorSubject<any>('');

getPopupSource() { 
   return this.popupSource.asObservable();
}

并订阅它而不是直接订阅主题本身。您可以在订阅时添加“asObservable()”部分,而不是创建一个全新的方法,但我喜欢单独的方法,因此我可以将主题保持为私有,而且我通常在不同的地方多次订阅某些东西一个应用程序,因此它减少了重复。

在您的组件中:

this._service.getPopupSource().subscribe( result => { etc...})

编辑:

您的场景的演示重现 - https://stackblitz.com/edit/angular-n6esd5

【讨论】:

  • 奇怪...我做了一个演示来重新创建您的示例,它的工作方式与我预期的一样。 angular-n6esd5.stackblitz.io 更多代码可能会有所帮助
  • 这太奇怪了,我在该服务中实际上还有 20 个其他功能,除了这个..
  • @GeoAstronaute 似乎认为它是如何提供的......因为它在我的 mainModule 和我的 appModule 中提供了两次......但我已经从 mainModule 中删除了它,它似乎仍然没有工作
  • 当我阅读他们的解释时,我认为这也可能是问题所在 - 通常,如果您想在整个应用程序中全局提供相同的服务实例,您会将其提供给最根模块(在您的案例应用程序模块中)。如果这不起作用,那么认为我和你一样困惑
  • 我不知道是否有一个真正令人信服的理由,我只是喜欢确定一个主题只能从服务本身内部控制。当我的应用程序变大并且我再也记不起脑海中的每一段代码时,可以更轻松地调试和推理。打字稿中的私有在实践中实际上只是“有点私有”,所以它可能只是个人喜好
【解决方案3】:

你可能没有相同的服务实例,我同样的问题是我的服务有@Injectable({ providedIn: 'root'}),而且我把这个服务放在组件提供者[]数组中,只需删除提供者数组,然后它就可以工作了

【讨论】:

    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    • 2018-07-21
    • 2018-09-27
    • 2018-10-29
    • 1970-01-01
    相关资源
    最近更新 更多