2017-02-10 146 views
0

我有一個爲WPF應用程序設置的標準reactive-ui路由,並且我有一個ViewModel可以實現的接口來提供標題信息。SelectMany後仍然訂閱Observable

public interface IHaveTitle 
{ 
    IObservable<string> Title { get; } 
} 

在一個視圖模型我做了以下(用於演示目的):

public IObservable<string> Title => Observable.Interval(TimeSpan.FromSeconds(5)).Select(_ => DateTime.Now.ToLongTimeString()); 

在我的主窗口畫面,我做了以下內容:

disposer(
    ViewModel.Router.CurrentViewModel 
    .SelectMany(vm => 
     ((vm as IHaveTitle)?.Title.StartWith("") ?? 
      Observable.Return("")).Select(s => string.IsNullOrEmpty(s) ? vm.UrlPathSegment : $"{vm.UrlPathSegment} > {s}")) 
    .ObserveOn(RxApp.MainThreadScheduler) 
    .BindTo(this, w => w.Title)); 

其中disposerAction<IDisposable>傳入this.WhenActivated的擴展方法。

現在,當我瀏覽時,標題確實會改變以反映UrlPathSegment,而在主視圖模型中,標題更新將顯示每5秒的時間。

但是我看到的問題是,即使當我導航到不同的視圖模型時,主視圖模型上可觀察的標題仍然會導致標題上的更改。

我的問題確實是:我如何防止這種情況發生?爲什麼我在離開時離開,因爲我選擇的是CurrentViewModel

回答

5

問題是使用SelectMany。你說「每次CurrentViewModel變化,訂閱這個其他可觀察的」。由於這些觀察者從未完成,他們永遠保持「活躍」。

你,而不是要開關新觀察到的:

disposer(
    ViewModel.Router.CurrentViewModel 
    .Select(vm => 
     ((vm as IHaveTitle)?.Title.StartWith("") ?? 
      Observable.Return("")).Select(s => string.IsNullOrEmpty(s) ? vm.UrlPathSegment : $"{vm.UrlPathSegment} > {s}")) 
    .Switch() 
    .ObserveOn(RxApp.MainThreadScheduler) 
    .BindTo(this, w => w.Title)); 
+0

我確實不知道如果'之開關是我一直在尋找,我只是從來沒有使用過它! – Clint