如何延迟 ReactiveCommand.CreateFromTask 第一次执行

How to delay ReactiveCommand.CreateFromTask first execution

我有一个使用 Xamarin.Forms 和 ReactiveUI 制作的应用程序。 在这个应用程序中想象一个视图,您有一种下拉菜单(实际上是一个按钮,可以推动另一个视图,用户可以在其中过滤和 select 一个选项)并且当这个 "dropdown" 被更改时,我需要重新加载基于其值的列表。

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

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

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

我需要 SelectedToDoList 中的 ID,但此时为空。

有什么方法可以延迟第一次执行命令?或者也许有更好的工作流程来解决这个问题?

这是我现在如何做的截图。如果需要更多信息,请告诉我。

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

如果我对你的问题理解正确,你需要确保 Id 不是 null,然后再调用 InvokeCommand:

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

也许更好的选择是将这些知识融入命令本身。因为 InvokeCommand 尊重命令的执行 window (从 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);