Как отфильтровать комбинировать, чтобы последние срабатывали только при изменении одного элемента? - PullRequest
0 голосов
/ 28 октября 2018

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

class ViewController: UIViewController {

    func loadData(page: Int, keyword: String) -> Observable<[Int]> {
        let _result = Observable.of([1,2,3,4])
        return _result
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let observable_keyword = PublishSubject<String>()
        let observable_page = PublishSubject<Int>()
        let trigger_tap = PublishSubject<Void>()

        let tapObservable = trigger_tap.debug("trigger_tap", trimOutput: true)
        let stringObservable = observable_keyword.debug("stringObservable", trimOutput: true)
        let pageObservable = observable_page.debug("pageObservable", trimOutput: true)

        let request_call_trigger = Observable.combineLatest(tapObservable, pageObservable)
            .debug("request_call_trigger", trimOutput: true)

        let page = request_call_trigger
            .withLatestFrom(stringObservable) { ($0, $1) }
            .flatMap { ((_, _, page), keyword) in
                Observable.combineLatest(Observable.just(page), self.loadData(page: page, keyword: keyword)) { (pageNumber: $0, movies: $1) }
                    .materialize()
                    .filter { $0.isCompleted == false }
            }
            .share()

        observable_keyword.onNext("breaking bad")
        observable_page.onNext(1)

        trigger_tap.onNext(())

        observable_keyword.onNext("orange is new black")
        observable_keyword.onNext("orange")

    }

    let bag = DisposeBag()
}

Я прочитал какой-то вариант, чувствовал, что фильтр или игнорирование могут работать здесь, но, поскольку мне нужно их значение в следующем, так растерянно, как правильно его применить.

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Вы можете использовать withLatestFrom , который согласно документации

Объединяет две наблюдаемые последовательности в одну наблюдаемую последовательность, комбинируя каждый элемент из себя с последним элементом из второго источника, еслилюбой

в вашем коде request_call_trigger имеет тип Observable<(Void, Int>), который вы комбинируете с последним значением из stringObservable, используя withLatestFrom.Это создает еще один кортеж типа Observable<(((Void, Int), String)>

, который вы можете flatMap на кортеже, созданном с помощью withLatestFrom, и передать значения страницы и ключевого слова в метод loadData, используя значение кортежа для страницы, которое составляет $ 0,1.так что нет необходимости использовать объединениеПоследний внутри flatMap.

        let tapObservable = trigger_tap.debug("trigger_tap", trimOutput: true)
        let stringObservable = observable_keyword.debug("stringObservable", trimOutput: true)
        let pageObservable = observable_page.debug("pageObservable", trimOutput: true)

        let request_call_trigger: Observable<(Void, Int)> = Observable.combineLatest(tapObservable, pageObservable)
            .debug("request_call_trigger", trimOutput: true)

        _ = request_call_trigger
            .withLatestFrom(stringObservable) { ($0, $1) }
            .flatMap { [weak self] (request_page_tuple: (Void, Int), keyword: String) -> Observable<Event<[Int]>> in
                guard let strongSelf = self else {
                    return Observable.empty()
                }
                return strongSelf
                    .loadData(page: request_page_tuple.1, keyword: keyword)
                    .materialize()
                    .filter { !$0.isCompleted }
            }
            .share()
0 голосов
/ 28 октября 2018

Если вы ищете один триггер, я думаю, что оператор, который вы ищете, это withLatestFrom:

observable2
  .withLatestFrom(observable1)

Значит: только при изменении observable2 - соберите его последнее испущенное значениес последним излученным значением наблюдаемой1.

edit : Если вам нужны оба значения, вам может потребоваться указать resultsSelector:

observable2
  .withLatestFrom(observable1) { ($0, $1) }
...