我有一个UITableView使用RxSwift填充反应式viewmodel,分页和刷新运行良好。 viewModel.dataSource()正在使用我的API,有时我可以收到一个解析为错误类型的空结果。
我想捕获此错误并创建一个空状态,隐藏tableview并显示一个emptyViewState。我以为我可以使用catchError来实现它。
我的问题是在catchError之后,dataSource被处理掉了,我无法恢复空状态并重新填充tableview,我试图重新创建调用self.bindDataSource()的dataSource但是我遇到了致命的错误。
有一种方法可以避免处理dataSource吗?如何重新连接/重建dataSource以从空状态恢复?
class MyViewControl: UIViewController {
fileprivate let disposeBag = DisposeBag()
fileprivate let viewModel = ViewModel()
let dataSource = SearchViewModel.SearchDataSource()
@IBOutlet fileprivate weak var tableView: UITableView!
@IBOutlet weak var emptyStateView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// When I disable tableview, can see a hidden view with empty state message and one button
viewModel.isTableViewHidden
.bindTo(tableView.rx.isHidden)
.addDisposableTo(disposeBag)
self.setupTableView()
}
fun setupTableView() {
// ... setup table view
self.bindDataSource()
}
fileprivate func bindDataSource() {
// Bind dataSource from search to UITableView
viewModel.dataSource()
.debug("[DEBUG] Loading Search Tableview ")
.bindTo( tableView.rx.items(dataSource: dataSource) )
.addDisposableTo( disposeBag )
}
@IBAction fileprivate func emptyStateAction(_ sender: UIButton) {
// Do something and try to recreate the bindDataSource
self.bindDataSource()
}
}
class SearchViewModel {
private let disposeBag = DisposeBag()
typealias SearchDataSource = RxTableViewSectionedReloadDataSource<PaginationStatus<WorkerEntity>>
let isTableViewHidden = BehaviorSubject<Bool>(value: false)
// Controls to refresh and paging tableview
let refreshTrigger = BehaviorSubject<Void>(value:())
let nextPageTrigger = PublishSubject<Void>()
// Others things happing herer
func dataSource() -> Observable<[PaginationStatus<WorkerEntity>]> {
return self.refreshTrigger.debug("[DEBUG] Refreshing dataSource")
.flatMapLatest { [unowned self] _ -> Observable<[PaginationStatus<WorkerEntity>]> in
// Access the API and return dataSource
}
.catchError { [unowned self] error -> Observable<[PaginationStatus<WorkerEntity>]> in
// Hidden the tableview
self.isTableViewHidden.onNext(true)
// Do others things
return Observable.of([PaginationStatus.sectionEmpty])
}
}
}
答案 0 :(得分:0)
当你使用bindDataSource()时,你不会重新初始化你的数据源,所以你将它绑定到一个错误事件。 你需要初始化它,再次绑定它。你可能也想要删除你的绑定
让disposeBagTableView = DisposeBag()
//remove
let dataSource = SearchViewModel.SearchDataSource()
fileprivate func bindDataSource() {
// Bind dataSource from search to UITableView
disposeBagTableView = DisposeBag()
SearchViewModel.SearchDataSource()
.debug("[DEBUG] Loading Search Tableview ")
.bindTo( tableView.rx.items(dataSource: dataSource) )
.addDisposableTo( disposeBagTableView )
}