数据未显示在 collectionView DiffableDataSource MVVM RxSwift 中
Data not display in 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 { [=10=].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: [=10=])})
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>()) {
[=10=].appendSections([.main])
[=10=].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
. 声明它们
- 像这样过度使用 BehaviorRelays 是一种代码味道。
- 上面的
map
应该放在你的 viewModel
而不是这里。
我正在学习 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 { [=10=].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: [=10=])})
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>()) {
[=10=].appendSections([.main])
[=10=].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
. 声明它们
- 像这样过度使用 BehaviorRelays 是一种代码味道。
- 上面的
map
应该放在你的viewModel
而不是这里。