我是RxJava的新手。我正在尝试“收听”列表更改:
filteredEvents = eventViewModel.getAllByInterval(dateStart, dateEnd);
Disposable disposable = filteredEvents.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
(events, throwable) -> {
if (throwable != null) {
throwable.printStackTrace();
return;
}
if (events != null) {
// do funny things
}
}
);
compositeDisposable.add(disposable);
现在:如果我想以动态方式更改已过滤的事件,例如更改dateStart和dateEnd间隔?我应该重新订阅新的列表内容吗?我想重用filteredEvents。提前致谢。
是的,你应该只处理你现有的一次性用品,并创造一个新的。这可能听起来很浪费,但没关系。
例如,对于网络请求,通常会触发网络请求,并且在它返回之前,触发新请求。您不再需要第一个,因此您只需要处理它,并且您实际上可以处理您想要响应的请求。
重新订阅新列表当然是一种选择,但对于视图逻辑来说这听起来太复杂了。尽量保持视图尽可能简单。你所有的观点需要做的只是这两件事:
可观察的过滤事件列表可以仅发射一次或多次。 View不应该关心它发出新列表的时间。您可以使用switchMap
和BehaviorSubject
在视图模型层中抽象所有切换逻辑,而不是在视图中使用多个订阅逻辑。
视图模型
public class EventViewModel {
private BehaviorSubject<Interval> interval = BehaviorSubject.create();
// Let view to subscribe to the filtered event list.
public Observable<List<Event>> getFilteredEvent() {
return interval.switchMap(interval -> getAllByInterval(interval.startDate, interval.endDate));
}
// Let view to request new event list. Note that this method returns nothing.
public void updateInterval(Date dateStart, Date dateEnd) {
interval.onNext(new Interval(dateStart, dateEnd));
}
// Make this private.
private Observable<List<Event>> getAllByInterval(Date startDate, Date endDate) {
...
}
private static class Interval {
final Date startDate;
final Date endDate;
Interval(Date startDate, Date endDate) {
this.startDate = startDate;
this.endDate = endDate;
}
}
}
请注意,EventViewModel
有两种公共方法。每个公共方法对应于上面定义的每个要求。
视图
// Do this only once:
compositeDisposable.add(eventViewModel.getFilteredEvent().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
(events, throwable) -> {
if (throwable != null) {
throwable.printStackTrace();
return;
}
if (events != null) {
// do funny things
}
}
));
// Do this as many times as you like. New list will be emitted
// by EventViewModel.getFilteredEvents.
eventViewModel.updateInterval(dateStart, dateEnd);
如果你使用Flowable
而不是Observable
,你可以用BehaviorSubject
替换BehaviorProcessor
。