【问题标题】:Observable still subscribed after SelectMany在 SelectMany 之后仍然订阅 Observable
【发布时间】:2017-02-10 20:32:11
【问题描述】:

我为 WPF 应用程序设置了标准响应式 UI 路由,并且我有一个 ViewModel 可以实现以提供标题信息的接口。

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));

其中disposer 是传递给this.WhenActivated 扩展方法的Action&lt;IDisposable&gt;

现在,当我四处导航时,标题确实会更改以反映 UrlPathSegment,而在主视图模型上,标题会更新为每 5 秒显示一次时间。

然而,我看到的问题是,即使我导航到不同的视图模型,在主视图模型上可观察到的标题仍然会导致标题发生变化。

我的问题是:我该如何防止这种情况发生?鉴于我是根据CurrentViewModel 选择的,为什么当我导航离开时它没有分离?

【问题讨论】:

    标签: c# wpf system.reactive reactiveui


    【解决方案1】:

    问题在于SelectMany的使用。您是在说“每次CurrentViewModel 更改时,订阅另一个可观察的”。由于这些可观察对象永远不会完成,因此它们永远保持“活跃”状态。

    你想切换到新的 observable:

    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));
    

    【讨论】:

    • 我确实想知道Switch 是不是我要找的东西,我以前从未使用过它!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 2018-03-13
    • 2017-11-30
    • 1970-01-01
    相关资源
    最近更新 更多