2016-04-02 23 views
2

我想實現一個Rx搜索視圖,該視圖將使用該字符串過濾回收視圖並檢查本地Realm數據庫並作出改進請求,然後結合所有結果而不重複?換句話說:我想在搜索視圖中使用輸入字符串進行網絡請求,使用數據庫查詢並結合結果而不重複如何創建一個Rx搜索視圖,該視圖將用查詢過濾回收站視圖

這是我的初始代碼:

RxSearchView.queryTextChanges(searchView) 
      .filter(charSequence -> !TextUtils.isEmpty(charSequence)) 
      .throttleLast(100, TimeUnit.MILLISECONDS) 
      .debounce(200, TimeUnit.MILLISECONDS) 
      .onBackpressureLatest() 
      .flatMap(charSequence -> userListPresenter.search(charSequence)) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribeOn(Schedulers.io()) 
      .onErrorResumeNext(Observable.empty()) 
      .subscribe((Action1) response -> userListPresenter.showSearchResult((List<UserModel>) response)); 

的userListPresenter.search(CharSequence的))應返回可觀察到的沒有重複的級聯反應,謝謝:)

userListPresenter.search(CharSequence中)):

Observable.create(subscriber -> { 
     if (Utils.isNetworkAvailable(getContext())) { 
      if (!subscriber.isUnsubscribed()) { 
       subscriber.onNext(restApi.search(query)); 
       subscriber.onCompleted(); 
      } 
     }).mergeWith(
        Observable.create(subscriber -> { 
     if (!subscriber.isUnsubscribed()) { 
      subscriber.onNext(realmManager.getWhere(query)); 
      subscriber.onCompleted(); 
     } 
    })).collect(HashSet::new, HashSet::add) 
      .flatMap(Observable::from); 

回答

3

如果我正確理解你的問題。有很好的方法來結合多個Observables的發射,看看zip method。 因此,您的搜索方式看起來像這樣:

public Observable<List<MyItem>> search(CharSequence query) { 
    return Observable.zip(
       observeNetwork(query), 
       observeRealm(query), 
       new Func2<List<MyItem>, List<MyItem>, List<MyItem>>() { 
        @Override 
        public List<MyItem> call(List<MyItem> networkResult, List<MyItem> databaseResult) { 
         return merge(networkResult,databaseResult); 
        } 
       } 
      ); 
} 

private Observable<List<MyItem>> observeRealm(CharSequence searchString) { 
    return Observable.create(/* do your realm stuff */); 
} 

private Observable<List<MyItem>> observeNetwork(CharSequence searchString) { 
    return return Observable.create(/* do your network stuff */); 
} 

private List<MyItem> merge(List<MyItem> networkResult, List<MyItem> databaseResult) { 
    List<MyItem> result = new ArrayList<>(); 
    result.addAll(databaseResult); 
    for(MyItem newItem : networkResult){ 
     if(!databaseResult.contains(newItem)){ 
      result.add(newItem); 
     } 
    } 
    return result; 
}