2017-02-21 26 views
1

我想將多個觀察者連接到一個共同主題。可觀察項目可能會被處置,並且新的觀察項目將被創建並由同一主題訂閱。在某些觀察者完成/處置後,讓主題「收聽」

我創建並刪除了幾個自定義的UIViews,每個自定義的UIView都包含發射到相同主題的觀察者。

例如:在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通知。這導致相同的ViewModel.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的知識/引用?我一直在努力讓自己的虛擬機孤島遠離VC和Views。 – HNK