组件中的订阅未从共享服务 Observable 接收值
Subscription in Component not receiving values from shared service Observable
我有这项服务:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MissionService {
// Observable string sources
private missionAnnouncedSource = new Subject<string>();
private missionConfirmedSource = new Subject<string>();
// Observable string streams
missionAnnounced$ = this.missionAnnouncedSource.asObservable();
missionConfirmed$ = this.missionConfirmedSource.asObservable();
// Service message commands
announceMission(mission: string) {
this.missionAnnouncedSource.next(mission);
}
confirmMission(astronaut: string) {
this.missionConfirmedSource.next(astronaut);
}
}
这个组件:
export class ComponentOne {
constructor(private service: MissionService) { }
onClick() {
console.log('entered in the onclick method');
this.service.announceMission('mission started');
this.service.missionAnnounced$.subscribe(response => console.log('from component 1: ' + response), error => console.log('error: ', error))
}
}
这个其他组件:
export class ComponentTwo {
constructor(private service: MissionService) {
console.log('entered in constructor ComponentTwo')
this.service.missionAnnounced$.subscribe(response => console.log('from component 2: ' + response),
error => console.log('error: ', error));
}
}
我不知道为什么 subscribe()
里面的 console.log
和 ComponentTwo
上的响应值从来没有被打印出来,甚至消息的一部分 from component 2:
永远不会出现。然而消息 entered in constructor ComponentTwo
总是出现.. 没有任何错误消息出现
使用 Subject
时,您只会收到调用 subscribe
之后发出的事件(值)通知。在这种情况下,我怀疑该服务在 ComponentTwo
中的订阅创建之前就发出了它的值。
如果您希望主题 "remember" 它的最后一个值,以便新订阅者看到最后一个值,请参见 BehaviorSubject.
另一种可能性是您独立地向两个组件提供服务,在这种情况下,您实际上将拥有两个不同的服务实例。这意味着在与 ComponentOne
关联的服务上发出的事件将不会被 ComponentTwo
看到,反之亦然。
为了让两个组件共享一个提供者的同一个实例,它通常应该在包含它们的@NgModule 中提供(具体来说 not 在两个地方列出,每个组件一个)。例如:
@NgModule({
declarations: [ComponentOne, ComponentTwo],
providers: [MissionService], // Will be shared by both components
// ...
})
export class AppModule {
}
我遇到了同样的问题,share 运算符有效。
An Observable that upon connection causes the source Observable to emit items to its Observers.
import 'rxjs/add/operator/share';
...
missionAnnounced$ = this.missionAnnouncedSource.asObservable().share();
missionConfirmed$ = this.missionConfirmedSource.asObservable().share();
我有这项服务:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MissionService {
// Observable string sources
private missionAnnouncedSource = new Subject<string>();
private missionConfirmedSource = new Subject<string>();
// Observable string streams
missionAnnounced$ = this.missionAnnouncedSource.asObservable();
missionConfirmed$ = this.missionConfirmedSource.asObservable();
// Service message commands
announceMission(mission: string) {
this.missionAnnouncedSource.next(mission);
}
confirmMission(astronaut: string) {
this.missionConfirmedSource.next(astronaut);
}
}
这个组件:
export class ComponentOne {
constructor(private service: MissionService) { }
onClick() {
console.log('entered in the onclick method');
this.service.announceMission('mission started');
this.service.missionAnnounced$.subscribe(response => console.log('from component 1: ' + response), error => console.log('error: ', error))
}
}
这个其他组件:
export class ComponentTwo {
constructor(private service: MissionService) {
console.log('entered in constructor ComponentTwo')
this.service.missionAnnounced$.subscribe(response => console.log('from component 2: ' + response),
error => console.log('error: ', error));
}
}
我不知道为什么 subscribe()
里面的 console.log
和 ComponentTwo
上的响应值从来没有被打印出来,甚至消息的一部分 from component 2:
永远不会出现。然而消息 entered in constructor ComponentTwo
总是出现.. 没有任何错误消息出现
使用 Subject
时,您只会收到调用 subscribe
之后发出的事件(值)通知。在这种情况下,我怀疑该服务在 ComponentTwo
中的订阅创建之前就发出了它的值。
如果您希望主题 "remember" 它的最后一个值,以便新订阅者看到最后一个值,请参见 BehaviorSubject.
另一种可能性是您独立地向两个组件提供服务,在这种情况下,您实际上将拥有两个不同的服务实例。这意味着在与 ComponentOne
关联的服务上发出的事件将不会被 ComponentTwo
看到,反之亦然。
为了让两个组件共享一个提供者的同一个实例,它通常应该在包含它们的@NgModule 中提供(具体来说 not 在两个地方列出,每个组件一个)。例如:
@NgModule({
declarations: [ComponentOne, ComponentTwo],
providers: [MissionService], // Will be shared by both components
// ...
})
export class AppModule {
}
我遇到了同样的问题,share 运算符有效。
An Observable that upon connection causes the source Observable to emit items to its Observers.
import 'rxjs/add/operator/share';
...
missionAnnounced$ = this.missionAnnouncedSource.asObservable().share();
missionConfirmed$ = this.missionConfirmedSource.asObservable().share();