2017-02-10 19 views
0

У меня есть стандартная маршрутизация, настроенная для WPF-приложения, и у меня есть интерфейс, который ViewModel может реализовать для предоставления информации о названии.Observable по-прежнему подписывается после SelectMany

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 - Action<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

Я сделал удивительно, если 'Switch' было то, что я искал, я бы просто не использовал его раньше! – Clint

 Смежные вопросы

  • Нет связанных вопросов^_^