我有一个用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);
答案 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);