В нашем проекте Xamarin.Forms у нас есть список элементов пользовательского интерфейса, где каждый элемент представляет собой POCO RealmObject (с именем Field) с такой информацией, как сериализованное значение, тип данных, дата последнего обновления времени и т. Д. c. Предполагается, что при обновлении RealmObject пользовательский интерфейс изменится, чтобы показать новое значение. Однако в действительности этого не происходит, и для получения правильных данных требуется уничтожить и повторно инициализировать представление. Мне интересно, есть ли способ сделать IObservable на основе обновления RealmObject, чтобы его можно было связать с представлением ReactiveUI.
Наш текущий конвейер данных включает в себя данные, поступающие с сервера, быть преобразованным в поле и перенесенным в область с флагом обновления. Затем у нас есть служба области, которая обрабатывает функции области, одной из которых является функция, которая возвращает IObservable, который содержит сериализованное значение поля. Я могу подтвердить, что данные, передаваемые в область из нашей службы обновлений, передаются правильно, и активный вызов для получения данных с помощью этих функций возвращает правильные данные. Единственный случай, когда он не работает должным образом, - это когда кто-то подписывается на IObservable и ожидает обновления. Ниже приведен соответствующий код.
Как заданы данные RealmObject:
var updateField = //Generate field data from server response, has same uniqueId as existingField
var existingField = realm.Find<Field>(uniqueId);
if (updateField != existingField)
{
realm.Add(updateField, update: true);
}
Текущая реализация RealmService:
public RealmService(byte[] encryptionKey, IScheduler scheduler, ...)
{
_realmStream = Observable
.Start(() => Realm.GetInstance(new RealmConfiguration { EncryptionKey = encryptionKey }), scheduler)
.Replay()
.AutoConnect();
}
public IObservable<string> GetFieldSerializedValueStream(string uniqueId)
{
return _realmStream
.Select(realm => realm.Find<Field>(primaryKey)?
.ObservableForProperty(field => field.SerializedValue, skipInitial: false)
.Select(pv => pv.GetValue()))
.Switch()
.SubscribeOn(_scheduler);
}
Код пользовательского интерфейса ViewModel: (Данные обрабатывается по-разному в зависимости от типа данных, но это общее описание)
private ObserableAsPropertyHelper<T> _data;
public T Data => _data.Value;
public UIDataView(string dataUniqueId, RealmService realmService, ...)
{
RealmService
.GetFieldSerializedValueStream(dataUniqueId)
.Select(serializedValue => /*De-serialize value*/)
.ToProperty(this, vm => vm.Data, out _data, RxApp.MainThreadScheduler)
}
Соответствующие пакеты NuGet: