2017-02-21 36 views
1

Я хочу подключить несколько наблюдаемых к общему вопросу. Наблюдаемые могут быть удалены, и новые наблюдаемые будут созданы и будут подписаны одним и тем же Субъектом.Держите тему «прослушивание» после того, как некоторые из ее наблюдателей полны/расположены

Я создаю и удаляю несколько пользовательских UIViews, в каждом из которых есть наблюдатели, которые испускают тот же объект.

Например: в myView1, у меня есть:

myButton1.rx.tap 
    .subscribe(sameViewModel.subject) 
    .disposed(by: disposeBag1) 

и в myView2, у меня есть:

myButton2.rx.tap 
    .subscribe(sameViewModel.subject) 
    .disposed(by: disposeBag2) 

В этом простом примере, sameViewModel.subject одно и то же PublishSubject в экземпляре (sameViewModel), который не деинируется, когда myView1 и myView2 удаляются.

Когда myView1 удален, его disposeBag1 удаляется, а myButton1.rx.tap испускает свои onComplete и onDispose уведомления. Это приводит к тому, что sameViewModel.subject также завершается и удаляется. Субъект больше не отвечает на дальнейшие события из myButton2.rx.tap или других наблюдаемых, которые я создаю позже.

Как создать/настроить отношения наблюдателя-субъекта, где объект остается активным, когда его наблюдатели расположены?

Может ли объект быть настроен на игнорирование всех событий/распоряжений? Нужно ли переписывать .subscribe для индивидуальной обработки onNext, onComplete и т. Д.? Есть ли какая-то закономерность?

ответ

1

Вам необходимо указать merge двух наблюдаемых наблюдателей в один наблюдаемый, а затем подписаться на него. Объединенный наблюдаемый не будет завершен до тех пор, пока все его компонентные наблюдаемые не будут завершены или не будут ошибочными.

let taps = Observable.from([button1.rx.tap, button2.rx.tap]).merge() 

Поскольку вы отметили, что эти кнопки приходят и уходят, вы могли бы вместо этого нужно использовать flatMap. Функция, вызывающая появление представлений, должна будет отображать наблюдаемые краны. Опять же, родительский наблюдаемый не завершит или не выйдет из строя, пока все его дети не сделают этого, но в этом случае его дети динамически генерируются.

func displayView() -> Observable<Void> { 
    // create and display view 
    return view.button.rx.tap.asObservable() 
} 

let taps = triggerToDisplayView().flatMap { displayView() } 
+0

Спасибо за понимание. Подход flatMap работал так, как вы объяснили, но когда наблюдаемые (краны) flatMap сами по себе, одна и та же цепочка событий происходит в моей первоначальной проблеме. – HNK

+0

Да. Наблюдаемые краны должны находиться в том же объектеViewModel. –

+0

Возможно, это связано с другим вопросом. Может ли это решение быть реализовано НЕ требуя, чтобы виртуальная машина имела собственный displayView() или любые знания/ссылки на Views? Я пытаюсь сохранить мой силос VM от VC и Views. – HNK