我如何在核心数据上创建一个可观察对象并将其绑定到tableView

问题描述 投票:1回答:2

我这样提取core data

var persistingData: [MyDataObject] = coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject"))

现在如何将这些数据用于Observable,可以将bind数据转换为rx tableView

我是否创建像这样的observable

func fetchAllData() -> Observable<[MyDataObject]> {
    var persistingData: [MyDataObject] = coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject"))

    return Observable.create({ observable in
        observable.onNext(persistingData)
        observable.onCompleted()
        return Disposables.create()
    })
}

但是如果我将数据传递给bind(),该如何在observable上使用onNext?像这样直接在bind上使用method

fetchAllData().bind()

我实际上如何将data放入observable,以便可以在bind()中使用?

EDIT

我也尝试过这种方法。这是一种有效的方法吗?

func fetchAllData() -> PublishRelay<[MyDataObject]> {
    var persistingData: [MyDataObject] = coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject"))

    let relay = PublishRelay<[LocalDoorCoreDataObject]>()
    relay.accept(persistingDoors)
    return relay
}

然后您可以像这样bind

viewModel.fetchAllData().bind(to: tableView.rx.items(cellIdentifier: Cell.identifier, cellType: Cell.self)) { row, data, cell in

    cell.viewModel = data

}.disposed(by: disposeBag)

这似乎合理,还是有其他方法?

uitableview observable bind rx-swift
2个回答
1
投票

Rx在处理数据流时特别有用,但是您尝试将其用作单个核心数据获取请求的简单包装。我将构建一个BehaviorRelay以保留来自Core Data的数据的副本,以及一个Observable,该Observable运行您的提取请求并向BehaviorRelay报告值,您可以在需要刷新的任何时间对其进行订阅。

具有您的视图模型:

let data = BehaviorRelay<[MyDataObject]>(value: [])

我将其绑定到您的表视图:

viewModel.data.bind(to: tableView.rx.items(cellIdentifier: Cell.identifier, cellType: Cell.self)) { row, data, cell in
    cell.viewModel = data

}.disposed(by: disposeBag)

然后返回您的视图模型:

var loadData: Observable<[MyDataObject]> {
   return Observable.deferred { [unowned self] in
      return Observable.just(self.coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject")))
   }.do(onNext: { [unowned self] data in
      self.data.accept(data)
   }
}

每当您需要刷新数据时,您只需致电:

viewModel.loadData.subscribe().disposed(by: disposeBag)

您可以使用loadData发出的值来立即更改UI,例如显示空白屏幕或停止加载指示器。如果您这样做,请确保在订阅前添加observeOn(MainScheduler.instance)


0
投票

让我们开始获取。

func fetchAllData() -> Observable<[MyDataObject]> {
    Observable.just(coreData.fetchAll(fetchRequest: NSFetchRequest<MyDataObject>(entityName: "MyDataObject")))
}

(上面的操作与fetchAllData所做的相同,但更简洁。)

现在考虑所有可能要获取数据的原因...假设您有一个刷新按钮,而只有当用户点击该按钮时,您才想获取所有数据。然后,在您的viewDidLoad(或从中调用的函数)中,您将拥有:

let allData = refreshButton.rx.tap 
    .flatMap { 
        fetchAllData()
    }

假设我们要在表格视图上显示数据。我们要在视图上重新加载数据的所有原因是什么?假设我们要重新加载数据的唯一原因是allData发出值时。然后,在viewDidLoad(或从中调用的函数)中,您还将具有:

allData
    .bind(to: tableView.rx.items(cellIdentifier: Cell.identifier, cellType: Cell.self)) { row, data, cell in
        cell.viewModel = data
    }
    .disposed(by: disposeBag)

我们走了,就这么简单。

现在,当您预想其他时候可能想要获取所有数据时,事情将会变得更加复杂,但是以上是基础知识。

© www.soinside.com 2019 - 2024. All rights reserved.