这种模式是否可以在ViewModel中由Akavache加载和缓存数据,并将它们绑定到Xamarin.Forms中的UI?



我正在尝试找到一些如何在现实世界场景中使用Xamarin.Forms,ReactiveUI和Akavache的'最佳实践'示例。 假设有一个简单的页面代表客户详细信息。它应该在激活(导航到)时从服务器检索数据。我喜欢Akavache的GetAndFetchLate扩展方法的想法,所以我想使用它。

我最终得到了这样的东西:

public class CustomerDetailViewModel : ViewModelBase //(ReactiveObject, ISupportsActivation) 
{
private readonly IWebApiClient webApiClient;
public Customer Customer { get; }
public ReactiveCommand<Unit, Unit> GetDataCommand { get; }
public CustomerDetailViewModel(Customer customer, IWebApiClient webApiClient = null) 
{
this.Customer = customer;
this.webApiClient = webApiClient ?? Locator.Current.GetService<IWebApiClient>();
GetDataCommand = ReactiveCommand.CreateFromTask(GetData);
}
private Task GetData()
{
BlobCache.LocalMachine.GetAndFetchLatest($"customer_{Customer.Id.ToString()}",
() => webApiClient.GetCustomerDetail(Customer.Id))
.Subscribe(data =>
{
CustomerDetail = data;
});
return Task.CompletedTask;
}
private CustomerDetail customerDetail;
public CustomerDetail CustomerDetail
{
get => customerDetail;
set => this.RaiseAndSetIfChanged(ref customerDetail, value);
}
}

DTO

public class Customer 
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class CustomerDetail 
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}

视图绑定

this.WhenActivated(disposables =>
{
this.OneWayBind(this.ViewModel, x => x.Customer.Name, x => x.nameLabel.Text)
.DisposeWith(disposables);
this.OneWayBind(this.ViewModel, x => x.CustomerDetail.Description, x => x.descriptionLabel.Text)
.DisposeWith(disposables);
this.ViewModel?.GetDataCommand.Execute().Subscribe();
}

但我认为这不是 100% 防弹的。这有一些可能的问题:

  1. 当我想在激活时加载数据时,是否可以在视图上this.WhenActivated(d => ...)调用this.ViewModel?.GetDataCommand.Execute().Subscribe();
  2. 绑定到CustomerDetail.Description会导致NullReferenceException我说得对吗?还是安全?
  3. 我想做一些类似的事情:"如果有CustomerDetail,请展示CustomerDetail.Name。当尚未加载时,显示Customer.Name"。因此,我需要在视图模型上创建特定的属性吗?
  4. 如何指示装载?
  5. 我在这里错过了一些重要的东西吗?我可能遇到的其他问题吗?
您可以在
  1. ViewModel中使用WhenActive,您可以在ISupportActivation实现一个接口。然后,您可以从 ViewModel 调用或运行GetData。还有一个名为InvokeCommand()的帮助程序扩展方法
  2. 我们故意不向下传播。我们使用自己的零传播形式。
  3. 在这种情况下
  4. ,您可能会在控件上设置文本是一种方式。在显示您的视图之前,不会发生"何时激活"。
  5. 我通常将其作为视图模型上的布尔属性来完成,视图模型可以考虑不同的命令等。您可能会对调用StartsWith(false)的命令执行ObservableAsPropertyHelper
  6. 我可能会在您的 BlobCache 上使用ObservableAsPropertyHelper,但看起来代码合理。

最新更新