【发布时间】:2016-11-09 17:34:48
【问题描述】:
基本上我想知道有没有办法在我订阅后立即从EventEmmiter 获取最后一个值?
为什么我需要这个。想象一个列表组件,它使用了另外两个组件:过滤器和网格。过滤器提供filter事件,网格提供sorting事件。
在我的列表组件中,我想编写如下代码:
Observable
.combineLatest(filtering$, sorting$)
.switchMap(([filter, sorting]) => {
return this.api.list(filter, sorting);
})
...
非常简短优雅的代码。但是有两个问题:
-
EventEmitteris not observable。这不是什么大问题,因为我可以很容易地用 observable 包装它。 - 在每个 observable 至少触发一次之前,不会执行对 API 的调用。这是一个真正的问题。
目前我正在使用来自 RxJs 的 BehaviorSubject 解决它:
表示随时间变化的值。观察者可以订阅主题以接收最后(或初始)值和所有后续通知。
在我的过滤器组件中,我有:
class UsersListFilter {
private filteringSource = new BehaviorSubject<UserFilter>(new UserFilter());
filtering$ = this.filteringSource.asObservable();
...
}
在我的列表组件中:
class UsersList {
@ViewChild(UsersListFilter) private filter: UsersListFilter;
...
setupDataReloading() {
Observable
.combineLatest(this.filter.filtering$, this.grid.sorting$)
...
}
}
如您所见,我根本不使用EventEmitter。但是这个解决方案在 Angular2 中感觉有点不自然,因为我忽略了与子组件交互的标准方式 (@Output)。
有什么想法吗?
【问题讨论】:
-
您可以使用
@Output并在UsersList中拥有一个 BehaviorSubject 订阅该 EventEmitter(观察者角色),同时充当filtering$(可观察角色) -
是的,我可以用
BehaviorSubject包装EventEmitter,但是我需要为其设置默认值。在我看来,这是 Filter 组件而不是 UsersList 组件的责任。 -
然后你可以让Filter组件在启动时发出默认值
-
如果我在它发出之后订阅它,那么默认值将永远丢失。
-
如果你在构造函数中发出它显然会丢失。我猜在 ngOnInit 中发射会起作用,否则你可以在 ngOnInit 中尝试 setTimeout(.., 0)
标签: typescript angular rxjs eventemitter