从带有DynamicData的api到ObservableCache的数据,定期更新

问题描述 投票:1回答:1

例如,我有api获取项目列表:

Task<ICollection<Item>> GetItemsAsync();

我想与ObservableCache<Item, int>合作。

所以,我创建了IItemsService

IObservableCache<Item, int> Items { get; }

实施:

private IObservableCache<Items, int> _items;

public IObservableCache<Items, int> Items => _items ?? (_items = Create().AsObservableCache().Publish().RefCount());

private IObservable<IChangeSet<Items, int>> Create()
{
    return ObservableChangeSet.Create<Items, int>(cache =>
    {
        var timer = Observable.Interval(TimeSpan.FromSeconds(1))
            .SelectMany(_ => _api.GetItemsAsync())
            .Retry()
            .Subscribe(matchInfos => cache.EditDiff(matchInfos, EqualityComparer<MatchInfo>.Default));

        return timer;
    }, item => item.Id);

然后我在视图模型中使用此服务来显示项目:

_service.Connect()
    .Transform(item => new ItemViewModel(item))
    .Bind(out items)
    .Subscribe(_ => Initialized = true);

Initialized属性需要显示/隐藏加载指标。

我有几个问题:

  1. 这是一个好方法吗?
  2. 当项目计数是0Initialized属性是true时,我需要显示“没有项目”。但如果服务器返回0项 - ObservableCache将不会提出通知,所以Initialized属性将是false。我该怎么办?
  3. 当我处理所有订阅时,计时器不会停止。我使用RefCount()但它没有帮助。
c# system.reactive dynamic-data reactiveui reactivex
1个回答
1
投票
  1. 使用ObservableChangeSet.Create是一种很好的方式,因为它很灵活,也允许重试/重复逻辑。但是Publish().RefCount()无法在您的示例中使用,因为您将其应用于缓存而不是可观察的更改集。您是否希望延迟加载缓存?如果是这样,我可以用一些例子来更新这个答案。
  2. 格伦的回答是正确的。出于优化原因,动态数据中的空更改通知被抑制。此限制正在被删除。见issue #206
  3. 有单元测试来涵盖ObservableChangeSet创建的资源的处理。请参阅ObservableChangeSetFixture.cs,因此我怀疑定时器未被处理的原因是缓存本身尚未处理并且它使订阅保持活动状态。
© www.soinside.com 2019 - 2024. All rights reserved.