Ищите более декларативный способ 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();
}
Есть пара проблем с кодом, который вы разместили. Я не знаю, хотите ли вы повторить проблемы или нет:
- Элементы, удаленные из коллекции, не удаляются из наблюдаемого потока.
- Наблюдаемый поток просто
Unit
значения, которые не дают подсказки относительно того, какой дочерний объект или какое свойство какого дочернего объекта было изменено. Это оставляет вас с обновлением всего, что кажется довольно неэффективным.
Ответ @Enigmativity исправляет пункт 1 и, вероятно, является наиболее правильным ответом с учетом опубликованной информации. Пункт 2 - это недостаток дизайна, который вы можете исправить.