Можно ли создать Observable для наблюдения за изменениями RealmObject? - PullRequest
0 голосов
/ 19 февраля 2020

В нашем проекте 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:

  • Область 4.1.0

  • ReactiveUI 9.20.1

  • Xamarin.Forms 4.4.0.991477

...