Как отложить первое выполнение ReactiveCommand.CreateFromTask

У меня есть приложение, созданное с помощью Xamarin.Forms и ReactiveUI. Представьте себе представление в этом приложении, где у вас есть своего рода раскрывающийся список (на самом деле кнопка, которая нажимает другое представление, где пользователь может фильтровать и выбирать один вариант), и когда этот "раскрывающийся список" изменяется, мне нужно перезагрузить список на основе его значения .

Этот «раскрывающийся список» не начинается с какого-то значения, мне нужно сделать асинхронный запрос, получить значение и затем обновить представление.

Проблема в том, что когда я создаю команду для загрузки документов:

LoadAllDocuments = ReactiveCommand.CreateFromTask<string, IEnumerable<Document>>(_ => m_service.GetAllDocumentsByTodoListAsync(SelectedTodoList.Id), canLoadAll, m_scheduler);

Мне нужен идентификатор из списка SelectedToDoList, но на данный момент он будет нулевым.

Есть ли способ отложить это первое выполнение команды? Или, может быть, есть лучший рабочий процесс для решения этой проблемы?

Вот снайпер о том, как я сейчас это делаю. Сообщите мне, если потребуется дополнительная информация.

LoadAllDocuments = ReactiveCommand.CreateFromTask<string, IEnumerable<Document>>(_ => m_service.GetAllDocumentsByTodoListAsync(SelectedTodoList.Id), canLoadAll, m_scheduler);
ChangeToDoListCommand = ReactiveCommand.CreateFromTask<DocumentListViewModel, bool>(vm => this.PushPageFromCacheAsync<ToDoListViewModel>((model) => model.ParentViewModel = this));

this.WhenActivated((CompositeDisposable disposables) =>
{
    SelectedItem = null;

    var SelectedTodoListChanged =
        this
            .WhenAnyValue(x => x.SelectedTodoList)
            .Throttle(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler)
            .Publish();

    SelectedTodoListChanged
        .Where(x => x == null)
        .Subscribe(async _ => SelectedTodoList = await viewService.GetMyToDoListByVaultAsync(RuntimeContext.Current.VaultId))
        .DisposeWith(disposables);

    SelectedTodoListChanged
        .Where(x => x != null)
        .InvokeCommand(LoadAllDocuments)
        .DisposeWith(disposables);

    SelectedTodoListChanged.Connect();

    LoadAllDocuments
        .ObserveOn(m_scheduler)
        .SubscribeOn(m_scheduler)
        .Subscribe(list => AddViewsToList(list.ToList()))
        .DisposeWith(disposables);

person Giusepe    schedule 13.01.2017    source источник


Ответы (1)


Если я правильно понял ваш вопрос, перед вызовом InvokeCommand вам необходимо убедиться, что Id не null:

SelectedTodoListChanged
    .Where(x => x?.Id != null)
    .InvokeCommand(LoadAllDocuments)
    .DisposeWith(disposables);

Возможно, лучший вариант - встроить эти знания в саму команду. Поскольку InvokeCommand учитывает окно выполнения команды (то есть с RxUI 7), если CanExecute вашей команды в настоящее время false, то InvokeCommand фактически не будет вызывать вашу команду:

var canLoadAllDocuments = this
    .WhenAnyValue(x => x.SelectedTodoList?.Id)
    .Select(id => id != null);
LoadAllDocuments = ReactiveCommand.CreateFromTask<string, IEnumerable<Document>>(
    _ => m_service.GetAllDocumentsByTodoListAsync(SelectedTodoList.Id), canLoadAll,
    canLoadAllDocuments,
    m_scheduler);

Теперь вы можете это сделать:

SelectedTodoListChanged
    .InvokeCommand(LoadAllDocuments)
    .DisposeWith(disposables);
person Kent Boogaart    schedule 13.01.2017
comment
У меня было заблуждение, что команда будет вызываться сразу же, когда я CreateFromTask, но я этого не хотел. Но на самом деле произошло то, что, поскольку команда не запускает модуль, который вы их называете, у меня было другое место для ее вызова. Ваш ответ помог найти эту проблему и улучшить код с помощью canLoadAllDocuments. - person Giusepe; 14.01.2017