我使用UIRefreshControl
+ Variable
绑定来重新加载数据。
1)我知道rx_refreshing
扩展程序中有一个RXCocoa
变量,但我无法在此上下文中使用它。
2)我绑定答案(数组的Variable
)两次。一旦我加载视图控制器,并在UIRefreshControl
刷新时再次加载。
3)我检查UIRefreshControl
是否令人耳目一新的部分看起来很尴尬。感觉它是否违背了使用反应的目的?
...
let answers: Variable<[Answer]> = Variable([])
override func viewDidLoad() {
loadAnswers()
.shareReplay(1)
.bindTo(answers)
.addDisposableTo(self.disposeBag)
setupRx()
}
func loadAnswers() -> Observable<[Answer]> {
return Network.rxArrayRequest(Spark.Answers)
}
func setupRx() {
rc.rx_controlEvent(.ValueChanged)
.map { _ in !self.rc.refreshing }
.filter { $0 == false }
.flatMapLatest { [unowned self] _ in
return self.loadAnswers()
}
.bindTo(answers)
.addDisposableTo(self.disposeBag)
rc.rx_controlEvent(.ValueChanged)
.map { _ in self.rc.refreshing }
.filter { $0 == true }
.subscribeNext { [unowned self] _ in
self.rc.endRefreshing()
}
.addDisposableTo(self.disposeBag)
}
...
答案 0 :(得分:13)
首先,它的不实际上正在运作。只是似乎才能正常工作。在您的代码中,在致电rc.endRefreshing()
之前,您实际上并没有等待网络请求完成。相反,您只是拨打网络电话,然后立即拨打endRefreshing()
。
// `rc.rx_controlEvent(.ValueChanged)` only gets called once,
// when the user pulls down.
rc.rx_controlEvent(.ValueChanged) // user pulled down to refresh
.map { _ in !self.rc.refreshing } // !true -> false
.filter { $0 == false } // false == false
.flatMapLatest { [unowned self] _ in
return self.loadAnswers() // request answers
}
.bindTo(answers)
.addDisposableTo(self.disposeBag)
rc.rx_controlEvent(.ValueChanged) // user pulled down to refresh
.map { _ in self.rc.refreshing } // true -> true
.filter { $0 == true } // true == true
.subscribeNext { [unowned self] _ in
self.rc.endRefreshing() // end refreshing
}
.addDisposableTo(self.disposeBag)
要解决问题1
,您是对的,您可以使用rx_refreshing
关闭刷新而不是endRefreshing()
。
要解决问题2
,我不认为Variable
是必要的或有用的,至少在本例中。你仍然可以使用它。此外,在两个地方loadAnswers()
没有必要。
要解决问题3
,是的,您可以简化这一点并使用Rx
更多。
以下代码实际可行,使用rx_refreshing
,并简化了很多事情:
let initial = Observable<Void>.just(())
let refresh = rc.rx_controlEvent(.ValueChanged).map { _ in () }
let answers = Observable.of(initial, refresh)
.merge()
.flatMapLatest{ _ in self.loadAnswers() }
.shareReplayLatestWhileConnected()
answers
.map { _ in false }
.bindTo(rc.rx_refreshing)
.addDisposableTo(disposeBag)
// also use `answers` to bind to your data source, etc.