Ищите более декларативный способ Rx для наблюдения за изменением свойств элемента

У меня есть коллекция, которую можно наблюдать с точки зрения Rx, предметы также можно наблюдать (с точки зрения Rx).

Я хочу иметь возможность наблюдать, когда изменяются свойства элементов в коллекции, но размер коллекции можно изменять - добавлять, удалять и т. Д. Когда это происходит, я хочу повторно подписаться на свойства элементов в коллекции.

У меня есть код, который работает, но я ищу что-то более элегантное \ декларативное без использования Subject.

    private _favourites = new ObservableCollection<Favourite>();
    ...

    public IObservable<Unit> FavouritesChanged()
    {
        var disposable = new SerialDisposable();
        var subject = new Subject<Unit>();

        _favourites.ObserveCollectionChanged()
            .Subscribe(x =>
                       {
                           disposable.Disposable = _favourites.Select(y => y.ObservePropertyChanged())
                               .Merge()
                               .Select(y => Unit.Default)
                               .Subscribe(subject);
                       });

        return subject;
    }       
}

2 ответа

Решение

С помощью .Switch() это то, что вам нужно. .Switch() занимает IObservable<IObservable<T>> и возвращает IObservable<T> который производит значения только из последних внутренних IObservable<T>, Он обрабатывает все отписки от предыдущих значений внешней наблюдаемой.

Попробуй это:

public IObservable<Unit> FavouritesChanged()
{
    return
        _favourites
            .ObserveCollectionChanged()
            .Select(c =>
                _favourites
                    .Select(y => y.ObservePropertyChanged())
                    .Merge()
                    .AsUnit())
            .Switch();
}

Есть пара проблем с кодом, который вы разместили. Я не знаю, хотите ли вы повторить проблемы или нет:

  1. Элементы, удаленные из коллекции, не удаляются из наблюдаемого потока.
  2. Наблюдаемый поток просто Unit значения, которые не дают подсказки относительно того, какой дочерний объект или какое свойство какого дочернего объекта было изменено. Это оставляет вас с обновлением всего, что кажется довольно неэффективным.

Ответ @Enigmativity исправляет пункт 1 и, вероятно, является наиболее правильным ответом с учетом опубликованной информации. Пункт 2 - это недостаток дизайна, который вы можете исправить.

Другие вопросы по тегам