如何将 ViewModel 绑定到 Collat​​ionview?

时间:2021-01-22 07:38:57

标签: swift uicollectionview rx-swift

我正在尝试将视图模型绑定到集合视图。但我不知道该怎么做。我正在使用 MVVM 模式和 RxSwift,而且我之前只尝试过表视图绑定。这是我的视图模型和我迄今为止完成的视图控制器代码。

class SearchViewModel: ViewModelType {
    private let disposeBag = DisposeBag()

    struct input {
        let loadData: Signal<Void>
    }

    struct output {
        let result: Signal<String>
        let loadApplyList: PublishRelay<friends>
    }

    func transform(_ input: input) -> output {
        let api = SearchAPI()
        let result = PublishSubject<String>()
        let loadApplyList = PublishRelay<friends>()

        input.loadData.asObservable().subscribe(onNext: { [weak self] in
            guard let self = self else { return }
            api.getFriend().subscribe(onNext: { (response, statuscode) in
                switch statuscode {
                case .ok:
                    if let response = response {
                        loadApplyList.accept(response)
                    }
                default:
                    print("default")
                }
            }).disposed(by: self.disposeBag)
        }).disposed(by: disposeBag)

        return output(result: result.asSignal(onErrorJustReturn: ""), loadApplyList: loadApplyList)
    }
}

这是我的 ViewModel 代码

func bindViewModel() {
       let input = SearchViewModel.input(loadData: loadData.asSignal(onErrorJustReturn: ()))
       let output = viewModel.transform(input)
       
   }

这是我的 ViewController 代码。
集合视图应该如何绑定?

1 个答案:

答案 0 :(得分:1)

您的视图模型应该如下所示:

class SearchViewModel {
    // no need for a disposedBag. If you are putting a disposeBag in your view model, you are likely doing something wrong.

    struct input {
        let loadData: Signal<Void>
    }

    struct output {
        let loadApplyList: Driver<[User]> // you should be passing an array here, not an object.
    }

    func transform(_ input: input) -> output {
        let api = SearchAPI()

        let friendResult = input.loadData
            .flatMapLatest {
                api.getFriend()
                    .compactMap { $0.0.map(Result<friends, Error>.success) }
                    .asDriver(onErrorRecover: { Driver.just(Result<friends, Error>.failure($0)) })
            }

        let loadApplyList = friendResult
            .compactMap { (result) -> [User]? in
                guard case let .success(list) = result else { return nil }
                return list.friends
            }

        return output(loadApplyList: loadApplyList)
    }
}

现在在你的视图控制器中,你可以像这样绑定它:

func bindViewModel() {
    let input = SearchViewModel.input(loadData: loadData.asSignal(onErrorJustReturn: ()))
    let output = viewModel.transform(input)

    output.loadApplyList
        .drive(collectionView.rx.items(cellIdentifier: "Cell", cellType: MyCellType.self)) { index, item, cell in
            // configure cell with item here
        }
        .disposed(by: disposeBag)
}
相关问题