我试图找到一些“最佳实践”示例,如何在现实场景中使用 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 上创建特定的属性吗? - 如何指示加载?
- 我在这里错过了一些重要的事情吗?我还有其他一些问题吗?