簡體   English   中英

數據未在 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 { $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() function 在值被接受到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)
}

上面使用了這個助手 function。 它是可選的,但我認為使用它時代碼看起來更干凈:

func with<T>(_ value: T, _ fn: (inout T) -> Void) -> T {
    var temp = value
    fn(&temp)
    return temp
}

順便一提...

  • BehaviorRelay永遠不應該是var ,總是使用let聲明它們。
  • 像這樣過度使用 BehaviorRelay 是一種代碼異味。
  • 上面的map應該放在您的viewModel中而不是這里。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM