使用RxSwift和Realm动态过滤结果

时间:2017-09-29 05:48:49

标签: ios swift realm rx-swift rxdatasources

我有一个非常简单的项目,我希望动态过滤UITableView中有关UISegmentedControl中的压缩索引的内容。我使用MVVM和RxSwift,Realm和RxDataSources。所以我的问题是,如果我要更新UITableView中的内容,我需要创建特殊的' DisposeBag,仅用于此目的,并且UISegmentedControl中的每个选项都会将其重新创建。只有在这种情况下,如果我理解正确,则会重新订阅订阅,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()
       }
     }
   }

1 个答案:

答案 0 :(得分:0)

不要记得这是否会让MVVM脱颖而出,但是变量不是你想要的吗?

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
}