Nob*_*adi 1 mvvm uikit tableview swift combine
使用组合和 UIKit,当 viewModel 中包含的数组发生更改时,我尝试更新我的表视图。我的表视图的数据源是单独的,因为我想重用该文件(不同的对象都有一个名称 var,因此表视图将显示名称列表)。
视图模型:
class ViewModel {
@Published var items = [ItemViewModel]()
let service = NetworkService()
init() {
fetchItems()
}
func fetchItems() {
service.fetchItems { items in {
self.items = items.map { ItemViewModel($0) }
}
}
Run Code Online (Sandbox Code Playgroud)
数据源:
class GenericDataSource: UITableViewDataSource {
var list = [String]()
func setList(_ list: [String]) {
self.list = list
}
// then the usual tableView datasource boilerplate
}
Run Code Online (Sandbox Code Playgroud)
视图控制器:
class ViewController: UIViewController {
let viewModel = ViewModel()
let tableDataSouce = GenericDataSource()
var subscriptions = Set<AnyCancellable>()
func setupBinding() {
// I want to: 1) map over viewModel.$items to get [item.name]
// 2) assign the list of names to tableDataSource.list
// 3) reload the tableview so the new values are displayed
}
Run Code Online (Sandbox Code Playgroud)
我不确定要使用什么组合功能。我当前(工作)代码如下:
func setupBinding() {
viewModel.$items.handleEvents(receiveOutput: { [weak self] items in
self?.dataSource.setList(items.map { $0.name })
// dispatch called because I get yelled at for not being on main thread
DispatchQueue.main.async {
self?.itemsTableView.reloadData()
}
})
.sink { _ in }
.store(in: &subscriptions)
}
Run Code Online (Sandbox Code Playgroud)
它有效,但我觉得我是在暴力强迫它。是否有更清晰的方法来执行与当前设置的绑定?
是否有更清晰的方法来设置代码,以便绑定更容易?
“更清洁”是主观的,但更“组合”的方式是:
viewModel.$items
.receive(on: DispatchQueue.main)
.sink { [weak self] items in
self?.dataSource.setList(items.map(\.name))
self?.itemsTableView.reloadData()
}
.store(in: &subscriptions)
Run Code Online (Sandbox Code Playgroud)
您还可以使用.map运算符来获取名称数组:
.map { $0.map(\.name) }
// ...
.sink { [weak self] names in
// ...
}
Run Code Online (Sandbox Code Playgroud)
但我认为这是一个品味问题。
| 归档时间: |
|
| 查看次数: |
4124 次 |
| 最近记录: |