2017-02-10 105 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