关于 RxSwift/RxCocoa 与 combineLatest 绑定的问题
Question about RxSwift/RxCocoa binding with combineLatest
下面是一个将viewModel的字符串数组绑定到UITableView的简单例子。
我想再订阅一个 viewModel.randomString 并在单元格中使用它。
我尝试如下使用 combineLatest,但当然我无法绑定到 tableview。
您对如何实施它有什么想法吗?
class SimpleViewModel {
var list = BehaviorRelay<[String]>(value: [])
var randomString = BehaviorRelay<String>(value: "")
func fetch() {
// Request...
list.accept(["result1", "result2", "result3"])
randomString.accept("Random...")
}
}
class SimpleViewController {
let tableView = UITableView()
let viewModel = ViewModel()
func foo() {
// It works well.
viewModel.list.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, element, cell) in
cell.textLabel?.text = element
}
// I want to bind the viewModel.list to the tableView and use the viewModel.randomString string together.
Observable.combineLatest(viewModel.list, viewModel.randomString)
// How???
// .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, element, cell) in
// cell.textLabel?.text = element + "RandomString" // I want to use the "RandomString" of viewModel.randomString
// }
}
}
您的 combineLatest
调用会生成一个 Observable<([String], String)>
,但为了绑定到 table 视图项目,您需要一个 Sequence
事物的可观察对象。
([String], String)
不是序列。这是一对东西。您需要找到一种方法将其转换为一系列事物。由于您希望每个单元格都具有相同的 randomString
,因此您可以使用这样的函数:
{ (list, randomString) in list.map { (element: [=10=], randomString: randomString) } }
将其转换为 [(String, String)]
,数组中每对中的第二个字符串为 randomString
。
如果只是把上面的函数传给Observable.map
,就可以把一个Observable<([String], String)>
转成Observable<[(String, String)]>
:
Observable.combineLatest(viewModel.list, viewModel.randomString)
.map { (list, randomString) in list.map { (element: [=11=], randomString: randomString) } }
.bind(to: tableView.rx.items(cellIdentifier: "cell")) {
(index, model, cell) in
cell.textLabel?.text = model.element + model.randomString
}.disposed(by: disposeBag)
下面是一个将viewModel的字符串数组绑定到UITableView的简单例子。
我想再订阅一个 viewModel.randomString 并在单元格中使用它。
我尝试如下使用 combineLatest,但当然我无法绑定到 tableview。
您对如何实施它有什么想法吗?
class SimpleViewModel {
var list = BehaviorRelay<[String]>(value: [])
var randomString = BehaviorRelay<String>(value: "")
func fetch() {
// Request...
list.accept(["result1", "result2", "result3"])
randomString.accept("Random...")
}
}
class SimpleViewController {
let tableView = UITableView()
let viewModel = ViewModel()
func foo() {
// It works well.
viewModel.list.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, element, cell) in
cell.textLabel?.text = element
}
// I want to bind the viewModel.list to the tableView and use the viewModel.randomString string together.
Observable.combineLatest(viewModel.list, viewModel.randomString)
// How???
// .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, element, cell) in
// cell.textLabel?.text = element + "RandomString" // I want to use the "RandomString" of viewModel.randomString
// }
}
}
您的 combineLatest
调用会生成一个 Observable<([String], String)>
,但为了绑定到 table 视图项目,您需要一个 Sequence
事物的可观察对象。
([String], String)
不是序列。这是一对东西。您需要找到一种方法将其转换为一系列事物。由于您希望每个单元格都具有相同的 randomString
,因此您可以使用这样的函数:
{ (list, randomString) in list.map { (element: [=10=], randomString: randomString) } }
将其转换为 [(String, String)]
,数组中每对中的第二个字符串为 randomString
。
如果只是把上面的函数传给Observable.map
,就可以把一个Observable<([String], String)>
转成Observable<[(String, String)]>
:
Observable.combineLatest(viewModel.list, viewModel.randomString)
.map { (list, randomString) in list.map { (element: [=11=], randomString: randomString) } }
.bind(to: tableView.rx.items(cellIdentifier: "cell")) {
(index, model, cell) in
cell.textLabel?.text = model.element + model.randomString
}.disposed(by: disposeBag)