ObservableChangeSet ждать, пока список не будет готов, прежде чем смотреть - PullRequest
0 голосов
/ 21 февраля 2020

У нас есть страница списка, где мы можем включить или отключить вещь ™, используя <switch /> Эта вещь ™ переключается с флагом IsActive

public class Thing
{
    /* ... */
    [Reactive] public bool IsActive { get; set; }
}

С учетом следующего прослушивателя изменений идея заключается в том, что при изменении свойства IsActive (взаимодействие пользователя с тумблером) мы вызываем _saveItemCommand, чтобы сохранить объект с новым IsActiveState.

public ObservableCollection<Thing> DataObjectList {get;} = new ObservableCollection<Thing>();

public MyClass()
{
    _saveItemCommand  = ReactiveCommand.CreateFromTask(SaveItemInternal);
    _listWatcher = DataObjectList
        .ToObservableChangeSet()
        .AsObservableList()
        .Connect()
        .WhenPropertyChanged(x => x.IsActive)
        .Throttle(TimeSpan.FromMilliseconds(250))
        .ObserveOn(RxApp.MainThreadScheduler)
        .Select(x => x.Sender)
        .InvokeCommand(_saveItemCommand);
}

public void OnNavigatingTo()
{
    var newItems = _myService.GetNewItems();
    DataObjectList.AddRange(newItems);
}

public void OnDestroy()
{
    _listWatcher?.Dispose();
}

Проблема, с которой я столкнулся, заключается в том, что при настройке списка команда, кажется, вызывается для последнего элемента в списке сразу после вызова AddRange.

Как я могу сделать это так что команда не вызывается, пока пользователь не переключит коммутатор в первый раз? Как правильно настроить этот слушатель?

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Скорее всего, вы захотите добавить оператор Where, чтобы указать, что его следует вызывать только на переключателе IsActivation.

    _listWatcher = DataObjectList
        .ToObservableChangeSet()
        .AsObservableList()
        .Connect()
        .WhenPropertyChanged(x => x.IsActive)
        .Throttle(TimeSpan.FromMilliseconds(250))
        .ToCollection()
        .Where(x => x.Any(value => value.IsActive))
        .ObserveOn(RxApp.MainThreadScheduler)
        .Select(x => x.Sender)
        .InvokeCommand(_saveItemCommand);

Итак, две строки, которые я добавил,

        .ToCollection()
        .Where(x => x.Any(value => value.IsActive))

ToCollection() преобразует его в наблюдаемый список, а Where будет ограничивать ваши наблюдаемые до изменения значений IsActive.

Вы можете добавить sh FirstAsync() звоните, если хотите, чтобы это произошло только один раз после звонка Where().

0 голосов
/ 25 февраля 2020

После комментариев к ответу Гленна и некоторых дополнительных разговоров с Родни, вот что наконец работает.

_listWatcher = DataObjectList
    .ToObservableChangeSet()
    .AsObservableList()
    .Connect()
    .WhenPropertyChanged(x => x.IsActive)
    .Throttle(TimeSpan.FromMilliseconds(250))
    .Skip(1)
    .DistinctUntilChanged()
    .ObserveOn(RxApp.MainThreadScheduler)
    .Select(x => x.Sender)
    .InvokeCommand(_createActivationsInternal);
...