有 2 个或更多组件订阅由 Injectable 提供的冷 Observable [重复]
Posted
技术标签:
【中文标题】有 2 个或更多组件订阅由 Injectable 提供的冷 Observable [重复]【英文标题】:Having 2 or more components subscribe to a cold Observable provided by an Injectable [duplicate] 【发布时间】:2017-11-16 04:50:41 【问题描述】:对不起,如果这是微不足道的。
我是 Angular 4 的新手,我正在努力解决一个看似简单的问题:有 2 个或更多组件订阅由(登录)Injectable
提供的Observable
。
我的目标是:
-
视图调用
component1
上的事件
component1
将调用 login.service
上的方法
login.service
将进行 REST 调用
响应是“广播”使用.next()
component1
和 component2
会做出相应的反应
当只有一个组件时,这非常有效,但是当我将另一个组件 subscribe()
s 引入到 Observable
时,第二个组件只会在开始时收到通知(即:它只接收一条消息)而 @ 987654333@ 继续按预期工作并接收所有消息。
我最初将Subject
和BehaviorSubject
与asObservable()
方法一起使用,但后来又退回到普通的Observable
,结果相似。
这里有一个 sn-p 来帮助演示:
login.service:
@Injectable()
export class LoginService
private _loggedIn = new BehaviorSubject<booelan>(false);
public loggedIn$ = this._loggedIn.asObservable();
login()
// call API service
this._loggedIn.next(true);
component1:
@Component(
selector: 'app-test1',
template: `<button (click)="login()"`,
providers: [ LoginService ]
)
export class AppTest1Component
subscription: Subscription;
observer: Observer;
constructor(private loginService: LoginService)
ngOnInit()
this.subscription = this.loginService.loggedIn$.subscribe(
state => console.log('got event!', state); ,
error => console.log('Error:', error),
() => console.log('Complete');
);
ngOnDestroy()
this.subscription.unsubscribe();
component2:
@Component(
selector: 'app-test2',
template: `<button (click)="login()"`,
providers: [ LoginService ]
)
export class AppTest2Component
subscription: Subscription;
observer: Observer;
constructor(private loginService: LoginService)
ngOnInit()
this.subscription = this.loginService.loggedIn$.subscribe(
state => console.log('got event!', state); ,
error => console.log('Error:', error),
() => console.log('Complete');
);
ngOnDestroy()
this.subscription.unsubscribe();
让多个组件订阅可能由服务提供的Observable
并接收所有消息的最简单方法是什么?
此处发布的问题:Angular - shared service between components doesn't work 与 Observables 和 Subscriptions 无关。
【问题讨论】:
这个问题可能与 observables 无关,但它解决了同样的问题。请阅读答案并在您的应用中尝试。 你太棒了。很抱歉没有花时间仔细阅读回复。我有隧道视野。 发生在我们最好的人身上:-) 【参考方案1】:正如 echonax 所解释的,您的问题似乎与 this topic 有关。
通过将 LoginService 添加为这两个组件的提供者,您实际上是在创建所述服务的 2 个实例。
@Component(
selector: 'app-test2',
template: `<button (click)="login()"`,
providers: [ LoginService ] /* you are creating a new instance of the service here /*
)
如果你想拥有相同的实例,或者所谓的共享服务,你必须在它们所在的模块中声明提供者,并在组件中删除提供者:
@NgModule(
...
providers: [LoginService],
...
)
如果您提到的两个组件位于单独的模块中,您必须在一个模块中将服务声明为提供者,然后将此模块导入另一个模块:
/* NgModule of the Module2 */
@NgModule(
imports: [
Module1], /* you import the module which has the service as provider */
providers: [] /* Really important point here, you have to leave providers blank or at least with no reference to the shared service, or you will create a new instance of the said service */
...
)
我不完全确定它会解决您的问题,但我几乎可以肯定,根据您提供的代码,无论如何您都必须在您的应用中使用共享服务。
【讨论】:
你说的都是对的。谢谢 Echonax 和 nvkfr。我整天都在为此苦苦挣扎。我已经在我的@NgModules 中声明了该服务,但是正如您在我的 sn-ps 中看到的那样,我愚蠢地在每个组件中实例化了一个新副本。一旦我从两个组件中删除了提供程序,一切都运行良好。谢谢!以上是关于有 2 个或更多组件订阅由 Injectable 提供的冷 Observable [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何将 2 个或多个 Http 隧道(例如 ngrok)与 2 个或多个 .net 不同的应用程序(需要处理图形 api 的不同订阅)一起使用?