简体   繁体   English

RxSwift:如何使用 ViewModel 在表格视图内的集合视图单元格中填充数据?

[英]RxSwift: How to populate the data in collection view cell inside the table view using ViewModel?

I do have following structure:我确实有以下结构:

- TableView
-- Custom Table View Cell
--- CollectionView
---- Custom CollectionView Cell

I want to understand that how can I pass the data from / using view model in this structure with RxSwift - MVVM Structure.我想了解如何使用 RxSwift - MVVM 结构在此结构中的视图 model 传递数据/使用视图 model。

Whenever I do get response from API it should update the data in table view rows and associated collection view cell respectively.每当我收到 API 的响应时,它应该分别更新表视图行和关联的集合视图单元格中的数据。

Here is an example I wrote just now to demonstrate how you can use RxSwift to do what you want.这是我刚刚写的一个例子,用来演示如何使用 RxSwift 做你想做的事。 Important Note: This is a rough example, not optimally written and not tested, I just wrote it using a text editor hope it helps you out.重要提示:这是一个粗略的示例,没有经过优化编写和测试,我只是使用文本编辑器编写的,希望对您有所帮助。 if not I will try to polish it when I have some more time.如果没有,我会在有更多时间时尝试打磨它。

class MyViewModel {
    // Lets say TableData is your model for the tableView data and CollectionData for your collectionView
    public let tableData : PublishSubject<[TableData]> = PublishSubject()
    public let collectionData : PublishSubject<[CollectionData]> = PublishSubject()

    private let disposeBag = DisposeBag()

    func fetchData() {
        // Whenever you get an update from your API or whatever source you call .onNext
        // Lets assume you received an update and stored them on a variable called newShopsUpdate 
        self.tableData.onNext(newTableDataUpdate)
        self.collectionData.onNext(newCollectionDataDataUpdate)
    }
}

class MyViewController: UIViewController {
    var tableData: BehaviorRelay<[TableData]> = BehaviorRelay(value: [])
    var collectionData:  BehaviorRelay<[CollectionData]> = BehaviorRelay(value: [])
    let viewModel = MyViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Setup Rx Bindings
        viewModel
            .tableData
            .observeOn(MainScheduler.instance)
            .bind(to: self.tableData)
            .disposed(by: DisposeBag())
        viewModel
            .collectionData
            .observeOn(MainScheduler.instance)
            .bind(to: self.collectionData)
            .disposed(by: DisposeBag())

        // Register yours Cells first as usual
        // ...
        // Setting the datasource using RxSwift
        tableData.bind(to: tableView.rx.items(cellIdentifier: "yourCellIdentifier", cellType: costumeTableViewCell.self)) { row, tableData, cell in 
            // Set all the cell properties here
            // Lets also assume you have you collectionView inside one of the cells
            cell.tableData = tableData

            collectionData.bind(to: cell.collectionView.rx.items(cellIdentifier: "yourCellIdentifier", cellType: costumeCollectionViewCell.self)) { row, collectionData, cell in 
                // Set all the cell properties here
                cell.collectionData = collectionData
            }.disposeBag(by: DisposeBag())
        }.disposed(by: DisposeBag())
    }
}

The simplest solution is to use an array of arrays.最简单的解决方案是使用 arrays 数组。

For example.例如。 Let's assume your API returns:假设您的 API 返回:

struct Group: Decodable {
    let items: [String]
}

Then your view model would be as simple as this:那么你的观点 model 会像这样简单:

func tableViewItems(source: Observable<[Group]>) -> Observable<[[String]]> {
    return source
        .map { $0.map { $0.items } }
}

When creating your cell, you can wrap the inner array into an observable with Observable.just() like this:创建单元格时,您可以使用Observable.just()将内部数组包装成一个可观察对象,如下所示:

// in your view controller's viewDidLoad for example.
        tableViewItems(source: apiResponse)
            .bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: CollectionTableViewCell.self)) { _, element, cell in
                Observable.just(element)
                    .bind(to: cell.collectionView.rx.items(cellIdentifier: "Cell", cellType: UICollectionViewCell.self)) { _, element, cell in
                        let label = (cell.viewWithTag(6969) as? UILabel) ?? UILabel()
                        label.tag = 6969
                        label.text = element
                        label.sizeToFit()
                        cell.addSubview(label)
                }
                .disposed(by: cell.disposeBag)
        }
        .disposed(by: dispsoeBag)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将数据从UI Table View传递到Table View Cell中的UI Collection View? - How to pass data from UI Table View to UI Collection View inside Table View Cell? 将数据从集合视图单元内的表视图单元传输到另一个集合视图单元(带有图片!) - Transfer data from table view cell inside a collection view cell, to another collection view cell [with picture!] 如何在表格视图单元格内创建集合视图 - How to create collection view inside table view cell 表视图单元格内的集合视图 - Collection View inside Table View Cell 如何使用 rxSwift 和 Moya 从 viewModel 绑定数据? - How to bind data from viewModel in view with rxSwift and Moya? 如何通过快速点击集合视图的单元格在表视图中重新加载数据 - How to reload data in table view by tapping the cell of collection view in swift 在swift 3中单击另一个表视图单元格的集合视图数据后,如何在表视图单元格中重新加载集合视图数据? - How to reload the collection view data in table view cell after clicking another table view cell's collection view data in swift 3? 具有多种自定义单元格类型的 RxSwift 表格视图 - RxSwift table view with multiple custom cell types tableview单元格内的集合视图重新加载数据 - collection view inside tableview cell reload data 无法在表格视图单元格内滚动集合视图(在情节提要中创建) - Unable to scroll Collection view inside Table view cell (created in Storyboard)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM