我正在通过official cookbook学习Angular2。
以下代码突然出现。为什么“missionAnnounced $”没有变量声明?让missionAnnounced $ = ... 以下代码的逻辑是什么?
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);
}
}
答案 0 :(得分:21)
Observable
仅允许订阅,而Subject
允许发布和订阅(主题是可观察的)。因此,使用Subject
可以将您的服务用作发布商和订阅者。
@Component({})
class ComponentOne {
constructor(private service: MissionService) {}
onClick() {
service.announceMission('mission started');
}
}
@Component({})
class ComponentTwo {
constructor(private service: MissionService) {
service.missionAnnounced$.subscribe(mission => console.log(mission))
}
}
@Component({})
class ComponentThree {
constructor(private service: MissionService) {
service.missionAnnounced$.subscribe(mission => console.log(mission))
}
}
现在每个想要订阅宣布任务的人都可以订阅。 ComponentOne
将是宣布任务宣布的事件。
为什么“missionAnnounced $”没有变量声明?
确实如此。 missionAnnounced$
是变量名称,以其可观察形式分配Subject
。类成员变量不使用let
以下代码的逻辑是什么?
订阅者订阅了observable($
变量),而发布商则调用announceMission
和confirmMission
。分别为missionAnnounced$
和missionConfirmed$
的所有订阅者都将收到这些活动。
答案 1 :(得分:4)
为了补充上一个答案,您可以在以下SO链接中找到大量详细信息:What are the semantics of different RxJS subjects?
简而言之,Rxjs主题实现了Observable
和Observer
接口(有关主题的不同风格和行为的更多详细信息,请参阅链接)。此处使用的标准主题充当管道,并通过其Observable
接口在其Observer
接口上接收的所有值。您在代码中看到的asObservable
函数调用隐藏了Observer
接口的实现,因此您不能在不应该使用时无意中使用它,即您只能在使用时使用此主题任何常规的观察。