Как мне создать наблюдаемую на основных данных и привязать ее к tableView - PullRequest
1 голос
/ 27 апреля 2020

Я получаю core data следующим образом:

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

Теперь, как мне go об использовании этих данных для 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()?

РЕДАКТИРОВАТЬ

Я тоже так пытался. Это правильный способ сделать это?

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)

Это кажется разумным, или есть какой-то другой способ?

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Давайте начнем с вашей выборки.

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

(Выше приведено то же самое, что и ваша fetchAllData, но более кратко.)

Теперь подумайте обо всех причинах, которые вам могут понадобиться чтобы получить данные ... Допустим, у вас есть кнопка refre sh, и вы хотите получить все данные только тогда, когда пользователь нажимает эту кнопку. Тогда в вашем 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)

Там мы go, это просто.

Теперь, конечно, вещи получат больше сложный, когда вы представляете себе другое время, когда вам может потребоваться получить все данные, но вышеизложенное является основами.

1 голос
/ 27 апреля 2020

Rx особенно полезен при обработке потоков данных, но вы пытаетесь использовать его в качестве простой оболочки вокруг одного запроса на выборку Core Data. Я бы построил BehaviorRelay для хранения копии данных, поступающих из Core Data, и Observable, который запускает ваш запрос на выборку и сообщает значения в BehaviorRelay, на который вы можете подписаться в любое время, когда вам нужно обновить sh .

Имея в вашем представлении модель:

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)
   }
}

В любое время, когда вам необходимо обновить sh данные, вы просто звоните:

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

Вы можете использовать значение, выданное loadData, чтобы немедленно внести изменения в ваш Пользовательский интерфейс, например отображение пустого экрана или остановка индикатора загрузки. Если вы это сделаете, обязательно добавьте observeOn(MainScheduler.instance) перед подпиской.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...