如何延迟ReactiveCommand.CreateFromTask首次执行

时间:2017-01-13 02:12:34

标签: reactiveui

我有一个用Xamarin.Forms和ReactiveUI制作的应用程序。 想象一下这个应用程序中的一个视图,你有一种下拉菜单(实际上是一个按钮,可以推送另一个视图,用户可以在其中过滤并选择一个选项)以及何时下载"下拉"已更改,我需要根据其值重新加载列表。

这"下拉"不会从某个值开始,我需要发出异步请求,获取值然后更新视图。

问题是,当我创建加载文档的命令时:

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

我需要来自SelectedToDoList的Id,但此时此值为null。

有什么办法可以推迟首次执行命令?或者可能有更好的工作流程来解决这个问题?

以下是关于我现在如何做的讽刺。如果需要更多信息,请告诉我。

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);

1 个答案:

答案 0 :(得分:3)

如果我正确理解您的问题,您需要在致电Id之前确保null不是InvokeCommand

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);