0

我有一个非常简单的项目,我想在其中动态过滤UITableView有关UISegmentedControl. 我将 MVVM 与 RxSwift、Realm 和 RxDataSources 一起使用。所以我的问题是,如果我想更新内容,UITableView我需要创建 'special' DisposeBag,仅用于此目的,并且在UISegmentedControlnil 中的每个选择并再次创建。只有在这种情况下,如果我理解正确,订阅会重新更新,并UITableView显示来自 Realm 的新结果。那么有没有更好的方法来做这样的操作呢?无需每次都订阅,当我在UISegmentedControl. 这是我的代码:

//ViewController
class MyViewController : UIViewController {

  //MARK: - Props
  @IBOutlet weak var tableView: UITableView!
  @IBOutlet weak var segmentedControl: UISegmentedControl!

  let dataSource = RxTableViewSectionedReloadDataSource<ItemsSection>()
  let disposeBag = DisposeBag()

  var tableViewBag: DisposeBag!
  var viewModel: MyViewModel = MyViewModel()

  //MARK: - View lifecycle
  override func viewDidLoad() {
    super.viewDidLoad()
    self.setupRxTableView()
  }

  //MARK: - Setup observables
  fileprivate func setupRxTableView() {
    dataSource.configureCell = { ds, tv, ip, item in
      let cell = tv.dequeueReusableCell(withIdentifier: "ItemCell") as! ItemTableViewCell
      return cell
    }

    bindDataSource()

    segmentedControl.rx.value.asDriver()
      .drive(onNext: {[weak self] index in
        guard let sSelf = self else { return }
        switch index {
        case 1:
          sSelf.bindDataSource(filter: .active)
        case 2:
          sSelf.bindDataSource(filter: .groups)
        default:
          sSelf.bindDataSource()
        }
      }).disposed(by: disposeBag)
  }

  private func bindDataSource(filter: Filter = .all) {
    tableViewBag = nil
    tableViewBag = DisposeBag()
    viewModel.populateApplying(filter: filter)
      }).bind(to: self.tableView.rx.items(dataSource: dataSource))
      .disposed(by: tableViewBag)
  }
}

//ViewModel
   class MyViewModel {
      func populateApplying(filter: Filter) -> Observable<[ItemsSection]> {
       return Observable.create { [weak self] observable -> Disposable in
         guard let sSelf = self else { return Disposables.create() }
         let realm = try! Realm()
         var items = realm.objects(Item.self).sorted(byKeyPath: "date", ascending: false)
         if let predicate = filter.makePredicate() { items = items.filter(predicate) }
         let section = [ItemsSection(model: "", items: Array(items))]
         observable.onNext(section)

         sSelf.itemsToken = items.addNotificationBlock { changes  in
           switch changes {
             case .update(_, _, _, _):
             let section = [ItemsSection(model: "", items: Array(items))]
             observable.onNext(section)
             default: break
          }
        }
        return Disposables.create()
       }
     }
   }
4

1 回答 1

0

不记得这是否打破了我的脑海中的 MVVM,但 Variable 不是你想要的吗?

Variable<[TableData]> data = new Variable<[TableData]>([])

func applyFilter(filter: Predicate){
  data.value = items.filter(predicate) //Any change to to the value will cause the table to reload
}

在 viewController 的某个地方

viewModel.data.rx.asDriver().drive
        (tableView.rx.items(cellIdentifier: "ItemCell", cellType: ItemTableViewCell.self))
{ row, data, cell in

    //initialize cells with data
}
于 2017-09-29T06:05:58.077 回答