【问题标题】:Angular 2 fail to subscribe with shared serviceAngular 2 无法订阅共享服务
【发布时间】:2017-01-20 20:50:35
【问题描述】:

我对 BehaviorSubject 有一些问题。以下是三个组件的共享服务:

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

@Injectable()
export class StageEndService {

  private stageNumber = new BehaviorSubject<number>(0);
  private stageNumberPassed = new BehaviorSubject<number>(0);

  stageNumber$ = this.stageNumber.asObservable();
  stageNumberPassed$ = this.stageNumber.asObservable();

  announceStageNumber(num) {
    this.stageNumber.last(num);
  }

  announceStageNumberPassed(num) {
    this.stageNumberPassed.last(num);

  }
}

这是改变服务价值的两个组件之一的第一部分:

import { StageEndService } from './../../../common/services/stage-end.service';

@Component({
...
providers: [StageEndService]
})

...
private value = 6;

constructor (private stageEndService: StageEndService) {

  this.stageEndService.announceStageNumber(value);

}

第二个组件类似,但改变了 stageNumberPassed 的值。

在我的最后一个组件中,我尝试订阅但失败(console.log 返回 0):

import { StageEndService } from './../../../common/services/stage-end.service';

// there's no provider here since it's not necessary if I'm correct

 constructor(private stageEndService: StageEndService) {}

ngOnInit() {
  this.stageNumberSubscription = this.recruitmentEndService.stageNumber$.subscribe(response => {
  this.stageNumber = response;
});

不知道问题出在哪里。当我记录传递给服务中的函数的值时,它会返回正确的数字。不知道这是否重要,但以防万一:最后一个组件(我尝试订阅的地方)是我第一次设置新值的第一个组件的孙子。

【问题讨论】:

  • last(...) 应该做什么?对我来说,你打算使用next()
  • 我不知道 .last() 方法,所以只是说用 .next() 或 .emit() 替换它。
  • 顺便问一下,你用的是哪个版本的angular2?
  • @micronyks 替换为 .next() 和 .emit()。两者都不起作用。我正在使用 RC5。

标签: angular typescript observable


【解决方案1】:

不要将服务添加到每个组件的提供者。这样每个组件都有自己的实例,您不能使用它在服务之间进行通信。

只在AppModule或共享父组件中提供一次服务。

【讨论】:

  • 做到了,只留下进口,但没有帮助。
  • 我有一个非常相似的设置和问题。试图通过我在模块提供程序中列出的“控制器”来切换菜单。一切都按预期注销,但从未调用订阅回调。从这里移除它(并移除可注射装饰器)为我修复了它。有趣的是,在 Augury 中检查确实揭示了我的菜单组件所依赖的“控制器”实例从未更改过值。仍然有疑问,将控制器列为提供者如何创建新实例?
  • 注册提供者就是创建实例。 Angular DI 为每个提供者创建一个实例。如果您在创建多个实例的组件上有多个提供程序或一个提供程序,那么您将获得尽可能多的服务实例(控制器)。你在哪里提供它也决定了哪个实例被注入到哪里。 Angular DI 从组件(指令、管道、服务)中搜索,该组件为组件上的提供者请求依赖关系,然后是其父级,如果在模块中注册的提供者中还没有找到。
【解决方案2】:
this.recruitmentEndService.stageNumber$.subscribe(response => {
  this.stageNumber = response;
});

应该是

this.stageEndService.stageNumber$.subscribe(response => {
  this.stageNumber = response;
});

【讨论】:

  • 感谢您的帮助,但问题一定出在其他地方,因为这两个都没有解决。
  • 第 4 点在你的情况下似乎有问题。
  • recruitmentEndService 替换为stageEndService 即可解决问题。
  • 不幸的是,这不是问题所在。我在发布问题时准备代码示例时出错。问题出在其他地方。我刚刚发现,当只有一个组件发出值变化时,它工作得非常好。但是当其他组件发出另一个值(使用服务中的第二个函数)时,订阅就会中断。
猜你喜欢
  • 2016-08-23
  • 2020-11-29
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 2016-06-29
  • 2016-04-30
相关资源
最近更新 更多