В настоящее время для наших запросов API мы используем Rx.Пример того, как мы его используем:
let orderRxService = OrderRxService.listAsShop(shopId, status: .active)
.repeatRequest(delay: 4)
.observeOn(MainScheduler.instance)
.subscribe( onNext: { [weak self] orders in
self?.orders = orders
self?.tableView.reloadData()
})
.disposed(by: disposeBag)
Получает все заказы для данного shopId
со статусом .active
.При каждом обновлении локальный orders
объект заменяется, и tableView перезагружается.
Это перезагружает весь tableView, которого мы хотим избежать.Сейчас я изучаю RxDataSources, но не могу понять, каким образом можно заставить это работать.
У объекта Order
есть другое свойство currentStatus
, которое может иметь 3 различных значения.То, что у нас есть, это tableView с 3 разными секциями, в каждой секции отображаются все ордера для currentStatus
.
Как это должно быть реализовано в RxDataSources?В идеале было бы привязать его к сервису, который я показал ранее (OrderRxService.....subscribe()..
).
Теперь у меня есть для настройки RxDataSources-types:
extension Order: IdentifiableType, Equatable {
public typealias Identity = String
public var identity: String {
return String(id)
}
public static func == (lhs: Order, rhs: Order) -> Bool {
return (lhs.timeCreated ?? 0) > (rhs.timeCreated ?? 0)
}
}
struct OrdersSection {
var header: String
var orders: [Order]
}
extension OrdersSection: AnimatableSectionModelType {
typealias Item = Order
typealias Identity = String
var identity: String {
return header
}
var items: [Item] {
set {
orders = items
}
get {
return orders
}
}
init(original: OrdersSection, items: [Order]) {
self = original
self.items = items
}
}
Что я пытался сделатьэто работает так:
// I tried to make our local orders a Variable (I don't like this between-step and would like this to be just [Order]).
var orders: Variable<[Order]> = Variable([])
fun viewDidLoad() {
super.viewDidLoad()
// Then I set the local orders-variable's value to the new value coming from our Rx service.
let orderRxDisposable: Disposable = OrderRxService.listAsShop(shopId, status: .active)
.repeatRequest(delay: 4)
.observeOn(MainScheduler.instance)
.map { $0.items }.subscribe( onNext: { [weak self] orders in
self?.orders.value = orders
})
// Here I setup the dataSource
let dataSource = RxTableViewSectionedAnimatedDataSource<OrdersSection>(
configureCell: { ds, tv, ip, item in
let cell = tv.dequeueReusableCell(withIdentifier: "OrderCell", for: ip) as! OrderCell
cell.addContent(item, tableView: tv, viewController: self, spotDelegate: self)
return cell
},
titleForHeaderInSection: { ds, ip in
return ds.sectionModels[ip].header
}
)
// Here I set up the three different sections.
self.orders.asObservable().observeOn(MainScheduler.instance)
.map { o in
o.filter { $0.currentStatus == .status_one }
}
.map { [OrdersSection(header: "Status one", orders: $0)] }
.bind(to: self.tableView.rx.items(dataSource: dataSource))
self.orders.asObservable().observeOn(MainScheduler.instance)
.map { o in
o.filter { $0.currentStatus == .status_two }
}
.map { [OrdersSection(header: "Status two", orders: $0)] }
.bind(to: self.tableView.rx.items(dataSource: dataSource))
self.orders.asObservable().observeOn(MainScheduler.instance)
.map { o in
o.filter { $0.currentStatus == .status_three }
}
.map { [OrdersSection(header: "Status three", orders: $0)] }
.bind(to: self.tableView.rx.items(dataSource: dataSource))
}
Возможно, есть разные аспекты, которые можно улучшить.Например, Variable<[Order]>
Я хотел бы быть просто [Order]
.И вместо того, чтобы сделать это наблюдаемым, можно ли его вообще пропустить и создать три разных раздела, наблюдая за нашим OrderRxService?
Возможно ли иметь что-то вроде:
OrderRxService.listAsshop(shopId, status: .active).observeOn(MainScheduler.instance)
// First section
.map { o in
o.filter { $0.status == .status_one }
}
.map { [OrdersSection(header: "Status one", orders: $0)] }
.bind(to: self.tableView.rx.items(dataSource: dataSource))
// Second section
.map { o in
o.filter { $0.status == .status_two }
}
.map { [OrdersSection(header: "Status two", orders: $0)] }
.bind(to: self.tableView.rx.items(dataSource: dataSource))
// Etc...
Спасибо залюбая помощь!