Home > Net >  How to clear datas on RxTableView
How to clear datas on RxTableView

Time:08-17

I'm stuck on RxCocoa problem.

I'm gonna implement clear tableView with Rx.

The app using MVVM with RxCocoa needs clear data for initializing tableView with infinite scroll.

But with binding tableView, I dunno how to clear it.

Thanks.

ViewController

self.viewModel.requestData() // request data to Server

 self.viewModel.output.hotDealList
            .scan(into: [ItemModel]()) { firstPosts, afterPosts in // For Infinite Scroll
                return firstPosts.append(contentsOf: afterPosts)
            }
            .bind(to: self.tableView.rx.items(cellIdentifier: "itemCell", cellType: HotDealTableViewCell.self)) { [unowned self] (index, item, cell) in
                self.setCellUI(item: item, cell: cell)
            }.disposed(by: self.bag)

ViewModel

struct Output {
        let hotDealList = BehaviorSubject<[ItemModel]>(value: [])
    }

func requestData(page: String = "0") {
        let _ = self.service.requestItemList(["page":page])
            .subscribe(
                onNext:{ response in
                    guard let serverModels = response.posts, !serverModels.isEmpty else {
                        return
                    }
                    self.output.hotDealList.onNext(serverModels)
                }
            ).disposed(by: self.bag)
    }

CodePudding user response:

The solution here is to expand the state machine that you already have started. A Moore Machine (which is the easiest state machine to understand) consists of a number of inputs, a state, a start state, and a number of outputs. It is expressed in Rx using the scan operator and an Input enum.

You already have the scan operator setup, but you only have one input, hotDealList. You need to include a second input for clearing.

Something like this:

enum Input { 
    case append([ItemModel])
    case clear
}

let state = Observable.merge(
    viewModel.output.hotDealList.map { Input.append($0) },
    viewModel.output.clear.map { Input.clear }
)
.scan(into: [ItemModel]()) { state, input in
    switch input { 
    case let .append(page):
        state.append(page)
    case .clear:
        state = []
    }
}

In Rx, the outputs of the state machine are expressed by bindings. You already have one:

state.bind(to: self.tableView.rx.items(cellIdentifier: "itemCell", cellType: HotDealTableViewCell.self)) { [unowned self] (index, item, cell) in
    self.setCellUI(item: item, cell: cell)
}
.disposed(by: bag)

If you need more, be sure to share your state observable.

BTW, using self inside the binder like that is a memory leak. I suggest you move the setCellUI(item:cell:) method into the HotDealTableViewCell class so you don't need self.

  • Related