在服务中避免 EventEmitter:
我不确定您的目标是什么,但在 服务 中使用 EventEmitter 是一种不鼓励的做法。根据 Angular 文档,EventEmitter 应该与对服务没有影响的 @Output 装饰器一起使用(它用于子组件与父组件的通信)。另一方面,它会迫使您暴露发射器。
@Injectable()
export class MyService {
@Output() // <<< has no effect
public events: EventEmitter<any> = new EventEmitter();
// ^^ makes the emitter public
}
更喜欢 Subject 或 BehaviorSubject 方法:
正如@Mark Rajcok 在另一个post 中所建议的,首选以下任何一种方法:
Subject 既是 Observable(因此我们可以 subscribe() 访问它)又是 Observer(因此我们可以在其上调用 next() 以发出新值)。我们利用此功能。 Subject 允许将值多播到许多观察者。我们不利用此功能(我们只有一个观察者)。
BehaviorSubject 是 Subject 的变体。它具有“当前值”的概念。我们利用这一点:每当我们创建一个 ObservingComponent 时,它都会自动从 BehaviorSubject 获取当前导航项的值。
在您的情况下,服务如下所示:
@Injectable({ providedIn: 'root' })
export class CrossEventService {
private _refreshSource$ = new Subject<any>();
public refreshStream$ = this._refreshSource$.asObservable();
public refreshSections(event: any) {
this._refreshSource$.next(event)
}
}
如果你想知道为什么要创建一个以 _refreshSource$ 为源的 refreshStream$,这是因为它在我们希望公开来自主题的数据但同时防止将新数据推回主题时很有用。
这就是为什么您需要像从组件中那样触发 refreshSections:
this.CrossEventService.refreshSections("");
然后订阅refreshStream$。请记住,订阅 refreshStream 的所有组件都将被激活并传入主题的新值:
import {Subscription} from 'rxjs/Subscription';
export class ObservingComponent {
subscription: Subscription;
event: any;
constructor(private _crossEventService:CrossEventService) {}
ngOnInit() {
this.subscription = this._crossEventService.refreshStream$
.subscribe(event => this.event = event)
}
ngOnDestroy() {
// prevent memory leak when component is destroyed
this.subscription.unsubscribe();
}
}
请注意,我添加了来自 RxJs 的订阅,以便在组件被销毁时取消订阅主题。还要清楚地知道要传递给.next({information}) 的信息,因为您可以跳过从EventEmitter 继承的event 语法。