swift - 数据未在 collectionView DiffableDataSource MVVM RxSwift 中显示
问题描述
我正在学习 MVVM 和 RxSwift,我想显示来自 GitHub api 的数据并填充到 collectionViewDiffableDataSource 中。但它没有显示我的数据,即使我的快照已经设置为接受我的数据。这是我的代码
class FollowersListViewModel {
let searchText = BehaviorRelay<String>(value: "")
let page = BehaviorRelay<Int>(value: 1)
var followers = BehaviorRelay<[FollowerViewModel]>(value: [])
var filterFollowers = BehaviorRelay<[FollowerViewModel]>(value: [])
let hasMoreFollower = BehaviorRelay<Bool>(value: false)
let isLoading = BehaviorRelay<Bool>(value: true)
private let manager: NetworkManager
let disposeBag = DisposeBag()
init(manager: NetworkManager) {
self.manager = manager
}
func fetchFollowers(with username: String) {
isLoading.accept(true)
searchText.asObservable()
.filter { $0.count > 2 }
.throttle(.seconds(3), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.flatMapLatest { query in
self.manager.getFollowers(with: query, page: self.page.value)
}.subscribe { followers in
self.isLoading.accept(false)
self.followers.accept(followers.map { FollowerViewModel(follower: $0)})
print(self.followers.value)
} onError: { error in
print(error)
}.disposed(by: disposeBag)
}
}
class FollowersListVC: UIViewController {
var viewModel: FollowersListViewModel
enum Section { case main }
var collectionView: UICollectionView!
var dataSource: UICollectionViewDiffableDataSource<Section, FollowerViewModel>!
override func viewDidLoad() {
super.viewDidLoad()
setupViewController()
setupSearchController()
setupCollectionView()
setupCollectionViewDataSource()
viewModel.fetchFollowers(with: username)
setupSnapshot()
}
private func setupCollectionViewDataSource() {
dataSource = UICollectionViewDiffableDataSource<Section, FollowerViewModel>(collectionView: collectionView, cellProvider: { (collectionView, indexPath, follower) -> UICollectionViewCell? in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FollowersCell.reuseID, for: indexPath) as! FollowersCell
cell.set(followerVM: follower)
return cell
})
}
private func setupSnapshot() {
var snapshot = NSDiffableDataSourceSnapshot<Section, FollowerViewModel>()
snapshot.appendSections([.main])
snapshot.appendItems(viewModel.followers.value)
DispatchQueue.main.async { self.dataSource.apply(snapshot, animatingDifferences: true) }
}
}
我不知道为什么,但这就像我的快照没有被调用,在 MVVM 中使用时似乎有所不同
解决方案
您的setupSnapshot()
函数在值被接受之前被调用followers
。我还没有使用过NSDiffableDataSourceSnapshot
,但你可能需要做这样的事情:
func setupSnapshot() {
viewModel.followers
.map { (followers) in
with(NSDiffableDataSourceSnapshot<Section, FollowerViewModel>()) {
$0.appendSections([.main])
$0.appendItems(followers)
}
}
.observe(on: MainScheduler.instance)
.subscribe(onNext: { [dataSource] snapshot in
dataSource.apply(snapshot, animatingDifferences: true)
})
.disposed(by: disposeBag)
}
上面使用了这个辅助函数。它是可选的,但我认为使用它时代码看起来更干净:
func with<T>(_ value: T, _ fn: (inout T) -> Void) -> T {
var temp = value
fn(&temp)
return temp
}
顺便一提...
BehaviorRelay
s 永远不应该var
,总是使用let
.- 像这样过度使用 BehaviorRelay 是一种代码异味。
map
以上应该放在你的而viewModel
不是这里。
推荐阅读
- sql - 为什么在表 (acct_trans) 中插入事务详细信息时出现 oracle 存储过程错误?
- sql-server - sql中的多个数据库创建脚本
- python - 使用日期时间作为键的嵌套字典中的 Python 字典 TypeError
- android - 热重载不起作用,需要热重启Flutter
- python - 从包含给定字数最大值的字符串列表创建子列表
- html - 我不知道如何解决这个悬停效果
- python-3.x - 通过Thonny中的Pico从pyserial问题名称错误导入序列
- haskell - 从安全货币中存储价值
- javascript - 如何连接 Mobx6 商店以响应 15.8 组件?'Uncaught Invariant Violation,Hooks 只能在函数组件的内部调用''
- typescript - 如何使对象内部的属性成为类型