2017-02-10 13 views
0

У меня есть EditText, а прямо под ним есть четыре вкладки в ViewPager, и то, что я сейчас делаю, выполняет запрос к службе Rest с использованием Retrofit при изменении текста.Выполнение нескольких различных вызовов для переоснащения, которые зависят от одного RxTextView

RxTextView.textChangeEvents(searchbar.getEditText()) 
      .debounce(400, TimeUnit.MILLISECONDS) 
      .filter(new Func1<TextViewTextChangeEvent, Boolean>() { 
       @Override 
       public Boolean call(TextViewTextChangeEvent text) { 
        return (text.text().length() > 2); 
       } 
      }) 
      .subscribeOn(AndroidSchedulers.mainThread()) 
      .observeOn(Schedulers.io()) 
      .switchMap(new Func1<TextViewTextChangeEvent, Observable<?>>() { 
       @Override 
       public Observable<?> call(TextViewTextChangeEvent textViewTextChangeEvent) { 
        String searchBarText = textViewTextChangeEvent.text().toString(); 

        switch (visibleTab) { 
         case TAGS: 
          return presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)); 
         case PEOPLE: 
          return presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0)); 
         case COMPANIES: 
          return presenter.executeSearchPostsByCompanies(searchBarText, String.valueOf(0)); 
         case JOBS: 
          return presenter.executeSearchPostsByJobs(searchBarText, String.valueOf(0)); 
         default: 
          return presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)) 
            .toCompletable().toObservable(); 
        } 

       } 
      }) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Observer<Object>() { 
      // here I use EventBus to pass the results to the Fragments (Tabs) 
      // ... code omitted ... 

Как вы можете заметить из кода для каждой закладки, у меня есть другой запрос.

Но теперь требования были изменены и для каждого изменения текста есть EditText. Мне нужно выполнить все четыре запроса одновременно.

Я много искал и выяснил, что могу использовать combineLatest' so I added all four calls to combLatest`, но поскольку все они зависят от изменений текста, ничего не произошло.

Observable.combineLatest(presenter.executeSearchPostsByTag(/** what to add as queryText **/), 
     presenter.executeSearchPostsByJobs(/** what to add here as queryText**/), //omits the other two calls) 

Как вы видите прямо выше, я не знаю, как передать queryText. Должен быть способ комбинирования кода combineLatest с кодом RxTextView.textChangeEvents(searchbar.getEditText())... до switchMap Я отправил его в начале, но я не смог его найти.

EDIT: хорошо возможно combineLatest был неправ, и я мог бы сделать что-то вроде:

   .map(new Func1<String, Boolean>() { 
       @Override 
       public Boolean call(String s) { 

        presenter.executeSearchPostsByTag(s, String.valueOf(0)); 
        presenter.executeSearchPostsByPeople(s, String.valueOf(0)); 
        presenter.executeSearchPostsByJobs(s, String.valueOf(0)); 
        presenter.executeSearchPostsByCompanies(s, String.valueOf(0)); 

        return true; 

       } 
      }) 

, но тогда я не знаю, как получить результаты подписчику

ответ

1

Вы близки , Просто замените распределительную карту на:

.flatMap(new Func1<TextViewTextChangeEvent, Observable<CombinedData>>() { 
    @Override 
    public Observable<CombinedData> call(TextViewTextChangeEvent textViewTextChangeEvent) { 
     String searchBarText = textViewTextChangeEvent.text().toString(); 

     return Observable.combineLatest(
       presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)), 
       presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0)), 
       ...); 
     }  
}) 

Для лучшей читаемости создайте способ извлечения комбайновой детали. Что-то вроде:

Observable<CombinedData> fetchData(String searchBarText) { 
    return Observable.combineLatest(
      presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)), 
      presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0)), 
      ...); 
} 

Но если вы можете, было бы лучше разбить его на четыре части. Объявите Observable:

Observable<TextViewTextChangeEvent> requestObservable = RxTextView.textChangeEvents(searchbar.getEditText()) 
     .debounce(400, TimeUnit.MILLISECONDS) 
     .filter(new Func1<TextViewTextChangeEvent, Boolean>() { 
      @Override 
      public Boolean call(TextViewTextChangeEvent text) { 
       return (text.text().length() > 2); 
      } 
     }) 
     .subscribeOn(AndroidSchedulers.mainThread()) 
     .observeOn(Schedulers.io()); 

Тогда вы подписались четыре раза, для каждого запроса:

.flatMap(new Func1<TextViewTextChangeEvent, Observable<Post>>() { 
    @Override 
    public Observable<Post> call(TextViewTextChangeEvent textViewTextChangeEvent) { 
     String searchBarText = textViewTextChangeEvent.text().toString(); 
     return presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)); 
     } 
}) 
.subscribe(... 
+0

Так что я могу подписаться четыре раза в 'requestObservable' Thats новое для меня !! Я проверю его позже с самого последнего момента, и я дам вам знать, как это происходит (и принять ответ!). Благодаря! – Mes