c# - 这种模式是否可以通过 Akavache 在 ViewModel 中加载和缓存数据并将它们绑定到 Xamarin.Forms 中的 UI?
问题描述
我试图找到一些“最佳实践”示例,如何在现实场景中使用 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% 防弹的。这有一些可能的问题:
- 当我想在激活时加载数据时可以调用视图
this.ViewModel?.GetDataCommand.Execute().Subscribe();
吗?this.WhenActivated(d => ...)
- 绑定到
CustomerDetail.Description
会导致NullReferenceException
我是对的吗?或者它安全吗? - 我想做一些类似的事情:“如果有
CustomerDetail
,显示CustomerDetail.Name
。当它还没有加载时,显示Customer.Name
”。因为它,我需要在 ViewModel 上创建特定的属性吗? - 如何指示加载?
- 我在这里错过了一些重要的事情吗?我还有其他一些问题吗?
解决方案
- 您可以在 ViewModel 中使用 WhenActivated,您可以实现一个接口
ISupportActivation
。GetData
然后,您可以从您的 ViewModel调用或运行。还有一个辅助扩展方法称为InvokeCommand()
- 我们故意不向下传播。我们使用我们自己的空传播形式。
- 在这种情况下,您可能会在控件上设置文本是一种方法。在显示您的视图之前,WhenActivated 不会发生。
- 我通常将其作为 ViewModel 上的布尔属性来完成,ViewModel 可以考虑不同的命令等。您可能会对
ObservableAsPropertyHelper
命令调用执行StartsWith(false)
- 我可能会
ObservableAsPropertyHelper
在您的 BlobCache 上使用 a 但看起来很合理的代码。
推荐阅读
- microservices - 微服务架构 - 数据库是否在服务的所有实例之间共享?
- java - 如何将字符串拆分为列表并在一行Java中修剪
- python - 识别模块级测试
- angular - 角度 wijmo flexgrid 向网格单元添加唯一 ID
- amazon-web-services - 具有 IAM 授权的 AWS WebSocket API
- clickhouse - Clickhouse SQL:将数据从长格式重塑为宽格式
- twig - 带树枝的条件显示
- javascript - 如何提交某种类型的表格
- android - 在 android 中使用 volley 库解析嵌套的 JSON 数组
- javascript - 如何将 API 生成的 JavaScript 变量作为表单的一部分传递给 php 变量?