【问题标题】:Need help on reduce part in RXSwift需要帮助减少 RXSwift 中的部分
【发布时间】:2020-06-27 06:51:32
【问题描述】:

我不知道如何修复以下代码。 我合并了两个单独的发布主题,我希望将结果绑定到我的 Tableview

    Observable.merge(myCardsViewModel.digitalCard.asObservable()
        .map { $0.map { item in MergeCardModel.init(bankId: item.bankId, cardNumber: item.cardNumber, holderName: item.holderName, id: item.id, isDigital: item.isDigital, status: item.status, expirationDate: "", expirationMonth: "", expirationYear: "")}
    }, card2CardMyCardsViewModel.mycardsItem.asObservable()
        .map { $0.map { item in MergeCardModel.init(bankId: item.bankId, cardNumber: item.cardNumber, holderName: item.holderName, id: "", isDigital: false, status: "", expirationDate: item.expirationDate, expirationMonth: item.expirationMonth, expirationYear: item.expirationYear) }})
        .reduce([], accumulator: +)
        .bind(to: tblView.rx.items) {(tv, row, item) -> UITableViewCell in
            

            
            return cell
    }.disposed(by: disposeBag)

【问题讨论】:

    标签: ios swift macos mvvm system.reactive


    【解决方案1】:

    使用 RxDataSource 绑定到 TableView。在我看来这是最好的。

    我给你发了代码,它使用了集合视图,但在 Rx 中的表格视图将是相同的实现。

    https://github.com/RxSwiftCommunity/RxDataSources

    这里是例子:

    视图模型:

    extension ModelListViewModel {
        enum Sections: SectionModelType, Equatable {
            static func == (lhs: ModelListViewModel.Sections, rhs: ModelListViewModel.Sections) -> Bool {
                switch (lhs, rhs) {
                case (.model(let lItem), .model(let rItem)):
                    return lItem == rItem
                }
            }
            
            typealias Item = Asset
            
            case model(models: [Item])
            
            var items: [Item]  {
                switch self {
                case .model(let models):
                    return models
                }
            }
            
            init(original: Sections, items: [Item]) {
                self = original
            }
        }
    }
    
    class ModelListViewModel {
        //inputs
        let didLoad = PublishSubject<Void>()
        let modelSelected = PublishSubject<Asset>()
        //outputs
        let sections: Driver<[Sections]>
        
        private let disposeBag = DisposeBag()
        private static var data: [ModelDTO] = {
            var array = [ModelDTO]()
            let firstModel = ModelDTO(url: ModelDTO.seatModel(), img: #imageLiteral(resourceName: "seat"), modelName: "Seat")
            let secondModel = ModelDTO(url: ModelDTO.big_910_Model(), img: #imageLiteral(resourceName: "910_big"), modelName: "Big_910")
            let thirdModel = ModelDTO(url: ModelDTO.big_730_Model(), img: #imageLiteral(resourceName: "730_big"), modelName: "Big_730")
            let fourthModel = ModelDTO(url: ModelDTO.small_730_Model(), img: #imageLiteral(resourceName: "910_small"), modelName: "Small_730")
            let fifthModel = ModelDTO(url: ModelDTO.normal_730_Model(), img: #imageLiteral(resourceName: "910_normal"), modelName: "Normal_730")
            let sixthModel = ModelDTO(url: ModelDTO.butcherSmallModel(), img: #imageLiteral(resourceName: "butcher_small"), modelName: "Butcher_Small")
            let seventhModel = ModelDTO(url: ModelDTO.butcherBigModel(), img: #imageLiteral(resourceName: "butcher_big"), modelName: "Butcher_Big")
            return [firstModel, secondModel, thirdModel, fourthModel, fifthModel, sixthModel, seventhModel]
        }()
        
        init(context: ARRouter.ModelListContext, modelsEntity: ModelsEntity) {
            //TODO: Make sections due to responce from BackEnd
            sections = didLoad
                .mapTo([Sections.model(models: ModelListViewModel.data)])
                .asDriver(onErrorDriveWith: .empty())
            
            modelSelected.map { $0.model.url }
                .unwrap()
                .bind(to: context.modelSelectedIn)
                .disposed(by: disposeBag)
        }
    }
    

    ViewController

    class ModelListViewController: BaseViewController {
        private struct Cells {
            static let modelListCell = ReusableCell<ModelListCell>(nibName: "ModelListCell")
        }
        
        @IBOutlet private weak var collectionView: UICollectionView! {
            didSet {
                collectionView.register(Cells.modelListCell)
                
                viewModel.sections
                    .drive(collectionView.rx.items(dataSource: dataSource))
                    .disposed(by: disposeBag)
    
                collectionView.rx
                    .modelSelected(Asset.self)
                    .bind(to: viewModel.modelSelected)
                    .disposed(by: disposeBag)
            }
        }
    
        private let disposeBag = DisposeBag()
        private let viewModel: ModelListViewModel
        private let dataSource: RxCollectionViewSectionedReloadDataSource<ModelListViewModel.Sections>
        
        init(viewModel: ModelListViewModel) {
            self.viewModel = viewModel
            self.dataSource = .init(configureCell: { (_, tableView, indexPath, item) -> UICollectionViewCell in
                let cell = tableView.dequeue(Cells.modelListCell, for: indexPath)
                cell.setupCell(with: item)
                return cell
            })
            super.init(nibName: "ModelListViewController", bundle: nil)
            
            rx.viewDidLoad
                .bind(to: viewModel.didLoad)
                .disposed(by: disposeBag)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            navigationController?.navigationBar.prefersLargeTitles = true
            title = "Models"
        }
    }
    

    我给你发送了如何使用它的好例子:)

    享受吧。

    【讨论】:

    • 我用 combineLatest 而不是 merge 解决了这个问题,它成功了。感谢您的关注。
    • 我们可以在外面交流吗? @Oleksandr Vaker
    猜你喜欢
    • 2011-12-18
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多