ReactiveUI 动态数据:WhenAnyValue、Mult。过滤器、自动刷新、分页集合

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

我找不到有关如何处理具有多个过滤器的实时集合的答案。

要求是利用 WhenAnyValue(多个过滤器) 和 AutoRefresh(x=>x.colproperty),绑定过滤器等,转换,并做一些最后的事情..(在本例中手动分页而不是虚拟化)

this.WhenAnyValue(x => x.Creations, x => x.PerPage, x => x.CurrentPage, x => x.IncludePublished, x => x.Search, x => x.ShowForReview)

          .Select(x => x.Item1.ToObservableChangeSet().AutoRefresh(x => x.Listing).ToCollection().Select(x => x
          .Where(x => wherefilters)
          .Reverse()
          .Skip(PerPage * (CurrentPage - 1))
          .Take(PerPage)

          .Select(x => new CreationViewModel(x)))
          .Do(x =>
          {
              if (x.Count() == 1)
                  SelectedCreation = x.First();
          })
          .Do(x =>
          FilteredCreations = x.ToObservableCollection()
              ).Subscribe()).Subscribe();

(提一下:我通常做 ToObservableChangeSet()...filter..transform..Bind(out readonlycollection) 我应该以某种方式打破这个吗?我发现 ToObservableChangeSet().Filter(this.WhenAnyValue....) somehwere 但似乎不再支持它。 我找不到如何处理此类情况的示例。 这虽然调用了 new CreationViewModel 太多次,但我猜这个被触发的次数会乘以 whenanyvalues 和自动刷新..

尝试为此类案例寻找资源,尝试将事情分解。

编辑

好吧,我拆分了可观察对象,添加了我之前错过的 AutoRefreshOnObservable。

我有两个主要问题:

(1) https://github.com/LTa2022/RUIDDMyExamples/blob/master/RUIDDMyExamples/PageExtensions.cs

如何正确计算最大页面,我使用 toCollection 的方法有效,但订阅次数太多(尝试采取(1)立即取消订阅,但根本不起作用) 我认为从这个 .PageEx() 扩展中更新 Paging 类对象的 MaxPage 是有意义的。

(2) https://github.com/LTa2022/RUIDDMyExamples/blob/master/RUIDDMyExamples/SampleListViewModel.cs

我已经实现了一个 viewmodelfactory,它通过使用 viewmodel 缓存来提供正确的结果,但我认为我的可观察链是错误的,并且重复地访问转换部分太多次。 (第 86 行)(或者也许这就是它的工作原理)

c# reactiveui dynamic-data
1个回答
0
投票

我认为你的问题在于,你将

Creations
转换为 ObservableChangeSet,然后使用
ToCollection
将其转换回完全形成的集合,这会导致每次发送一个项目时都会发送一个新集合在源列表中更新(创作)。

我建议尝试将昂贵的过滤/重新排序任务应用到代码的

IObservable<IChangeSet<T>>
部分。

例如:

var refreshObs = this.WhenAnyValue(
        x => x.PerPage, // probably not needed, see pageRequestObservable below
        x => x.CurrentPage, // probably not needed, see pageRequestObservable below
        x => x.IncludePublished,
        x => x.Search, 
        x => x.ShowForReview);

Creations.ToObservableChangeSet()
     .AutoRefreshOnObservable(refreshObs)
     .AutoRefresh(x=> x.List) // This will only fire if you _replace_ the List (or trigger OnPropertyChanged for the List property). Is this what you want?
     .Filter(x => wherefilters) // I *think* this has the same signature as Where()
     .Reverse() // I've never used this in a IChangeSet observable, so double check this
     .Page(pageRequestObservable)
     .Transform(x => new CreationViewModel(x), transformOnRefresh: false) // default is false. Set true if you want a new VM created every time refreshObs ticks.
     .Bind(out _filteredCreations)
     .ToCollection()
     .Do(x =>
          {f
              if (x.Count() == 1)
                  SelectedCreation = x.First();
          })
     .Subscribe();

创建和使用

_filteredCreations
的位置(如此处所述):

private ReadOnlyObservableCollection<CreationViewModel> _filteredCreations;

public ReadOnlyObservableCollection<CreationViewModel> FilteredCreations => _filteredCreations

pageRequestObservable
可以通过使用创建(更多示例来自此处的测试

var pageRequestObservable = this.WhenAnyValue(x=> x.CurrentPage).CombineLatest(this.WhenAnyValue(x=> x.PerPage), (page, perPage) => new PageRequest(page, perPage))

我认为这不能完全解决您的问题,因为我不完全确定您想要如何触发过滤器,但它应该让您指向正确的方向。

现在,如果需要应用这些过滤器才能在 UI 上看到,您可以考虑使用

CollectionViewSource
更多信息此处

© www.soinside.com 2019 - 2024. All rights reserved.