Я пытаюсь разработать систему разбиения на страницы в приложении iOS с помощью RxSwift. Вариант использования прост: пользователь может вводить текст в поле поиска, а приложение выполняет запрос, который разбит на страницы. Когда он изменяет значение, новый запрос выполняется на первой странице (это означает, что значение наблюдаемого должно быть сброшено до 1). Если пользователь очищает поле поиска (или вводит текст с менее чем двумя символами), список результатов очищается и текущая страница сбрасывается. Следующая страница выбирается, когда пользователь прокручивается в нижнюю часть списка.Как объединить два наблюдаемых в реактивных расширениях для того, чтобы отображать результаты?
Это не случайный случай или iOS, и я полагаю, он может быть написан идентичным образом с использованием RxKotlin или RxJs или любого другого реактивного расширения.
Моя текущая попытка - установить наблюдаемое для текста и наблюдаемое для текущей страницы и объединить их для выполнения запроса с обоими параметрами. Мне уже удалось выполнить именно то, что я ищу, но используя глобальные атрибуты для хранения текущего запроса и текущей страницы. Я хотел бы найти способ использовать только значения, излучаемые наблюдаемыми, без необходимости их поддерживать (я думаю, что код будет более кратким и легким для чтения и понимания).
Вот мой текущий код:
// self.nextPage is a Variable<Int>
let moreObs: Observable<Int> = self.nextPage.asObservable()
.distinctUntilChanged() // Emit only if page has changed.
// self.searchTextObservable is a PublishedSubject<String> that receives the values from the textfield
let searchObs: Observable<String> = self.searchTextObservable
.throttle(0.4, scheduler: MainScheduler.instance) // Wait 400ms when the user stops writing.
.distinctUntilChanged() // Emit only if query has changed.
self.resultsObservable = Observable
.combineLatest(searchObs, moreObs) { query, page in
return ["q": query, "p": "\(page)"]
}
.subscribeOn(MainScheduler.instance) // Emit on main thread.
.observeOn(ConcurrentDispatchQueueScheduler(globalConcurrentQueueQOS: .Background)) // Perform on background thread.
.map { params in
if params["q"]!.characters.count > 2 {
return params
}
return [:]
}
.flatMap { params in
return params.isEmpty ?
Observable.of([]) :
self.search(params)
}
.map { results in
if results.count > 0 {
self.results.appendContentsOf(results)
} else {
self.results = []
}
return self.results
}
До сих пор единственная функция, которая не работает является операция сброса на стоимости СледующаяСтраница в. Если бы я заставить его 1
когда searchObs излучает:
let searchObs: Observable<String> = self.searchTextObservable
.throttle(0.4, scheduler: MainScheduler.instance) // Wait 400ms when the user stops writing.
.distinctUntilChanged() // Emit only if query has changed.
.map {query in
self.nextPage.value = 1
return query
}
Тогда у меня есть 2 запросы, которые выполняются.
Я злоупотребляю Rx?
Это прекрасно! – obo