繁体   English   中英

这种模式是否适合在ViewModel中通过Akavache加载和缓存数据并将它们绑定到Xamarin.Forms中的UI?

[英]Is this pattern OK for loading&caching data by Akavache in ViewModel and binding them to UI in Xamarin.Forms?

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

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

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.ViewModel?.GetDataCommand.Execute().Subscribe(); this.WhenActivated(d => ...)当我想在激活时加载数据时,在视图上激活this.WhenActivated(d => ...)
  2. 绑定到CustomerDetail.Description会导致NullReferenceException我是对的吗? 还是安全的?
  3. 我想做一些事情:“如果有CustomerDetail ,请显示CustomerDetail.Name 。当它尚未加载时,显示Customer.Name ”。 我是否需要在ViewModel上制作特定的属性?
  4. 如何表明装载?
  5. 我错过了一些重要的东西吗? 我可以用其他一些问题吗?
  1. 您可以在ViewModel中使用WhenActivated,有一个可以实现ISupportActivation的界面。 然后,您可以从ViewModel调用或运行GetData 还有一个名为InvokeCommand()的辅助扩展方法
  2. 我们刻意不要传播。 我们使用自己的零传播形式。
  3. 在这种情况下,您可能会在控件上设置文本。 在您的视图显示之前,不会发生WhenActivated。
  4. 我通常将此作为ViewModel上的布尔属性,ViewModel可以考虑不同的命令等。您可以对调用StartsWith(false)的命令执行ObservableAsPropertyHelper StartsWith(false)
  5. 我可能会在你的BlobCache上使用ObservableAsPropertyHelper ,但看起来合理的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM