组件中的订阅未从共享服务接收值Observable

时间:2017-12-20 21:32:47

标签: angular angular-services angular-components

我有这项服务:

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));
        }
    }

我不知道为什么永远不会打印console.logsubscribe()ComponentTwo的回复值,即使是消息的一部分from component 2:永远不会出现。但是,entered in constructor ComponentTwo消息始终显示..没有任何错误消息显示

2 个答案:

答案 0 :(得分:2)

使用Subject时,您只会收到调用subscribe后发出的事件(值)的通知。在这种情况下,我怀疑在创建ComponentTwo中的订阅之前服务正在发出其值。

如果您希望主题“记住”其最后一个值,以便新订阅者将看到最后一个值,请参阅例如BehaviorSubject

另一种可能性是您独立地向两个组件提供服务,在这种情况下,您实际上将有两个不同的服务实例。这意味着ComponentOne不会看到与ComponentTwo相关联的服务上发出的事件,反之亦然。

为了让两个组件共享同一个提供者实例,它通常应该在包含它们的@NgModule中提供(并且具体地在两个地方列出,每个组件一个) 。例如:

@NgModule({
  declarations: [ComponentOne, ComponentTwo],
  providers: [MissionService],  // Will be shared by both components
  // ...
})
export class AppModule {
}

答案 1 :(得分:0)

我遇到了同样的问题而且share运算符有效。

  

一个Observable,在连接时导致源Observable向其观察者发射项目。

import 'rxjs/add/operator/share';
...
missionAnnounced$ = this.missionAnnouncedSource.asObservable().share();
missionConfirmed$ = this.missionConfirmedSource.asObservable().share();