ReactiveUI рекомендует использовать динамические данные в будущем.Я пытаюсь перенести то, что имеет смысл, поскольку мне приходится работать с моими моделями представлений.
Недавно я столкнулся с проблемой, которую, похоже, не могу найти решение.На одной из моих страниц динамические данные используются с SourceCache
из 100 000 элементов, к которым мне нужно применить динамические фильтры и сортировки.
Эта проблема заключается в том, что даже если фильтрация по 100 000 происходит относительно быстро на мобильном устройстве пользователь не имеет представления, закончили ли мы фильтрацию или нет.Самый простой способ сообщить пользователю, что мы что-то делаем, - использовать IsRefreshing
на моем ListView
.
Вот здесь и начинается проблема ...
Я могу знать, когда фильтрация запускает , так как я строю триггер Observable, я просто могуНе найти надежный способ узнать, когда фильтрация завершается (не всегда).
В первый раз, когда фильтр запускается и возвращает 0 результатов, все работает, как и ожидалось, он просто не будет вызывать 0 результатов (изменений) снова после начального времени, пока мы не получим хотя бы одно изменение в результатах.
Это означает, что я могу показывать и скрывать счетчик обновления, пока фильтр дает «изменения» в наборе результатов, но как только пользователь выберет 0 результатов, последующий поиск 0 результатов приведет к 0 изменениям результатов ине будет запускать Observable ... Вращатель будет просто вращаться, пока фильтр не даст по крайней мере 1 изменение.
Вот код, иллюстрирующий эту проблему: (используя SourceList
для простоты)
var disposables = new CompositeDisposable();
var sourceList = new SourceList<string>();
ReadOnlyObservableCollection<string> results;
using (disposables)
{
// Create 100,000 dummy strings to start with
sourceList.Edit(
(innerList) =>
{
Enumerable
.Range(1, 100000)
.ForEach(x => innerList.Add(x.ToString()));
});
// Fake text trigger to replicate WhenAnyValue
var trigger = new Subject<string>();
disposables.Add(trigger);
// Dynamic filter
var filter = trigger
.Do(s =>
{
Console.WriteLine($"\r\nSearching for: {s}");
})
.Select(
searchTerm =>
{
Func<string, bool> searcher = item => item.StartsWith(
searchTerm,
StringComparison.InvariantCultureIgnoreCase);
return searcher;
});
disposables.Add(
sourceList
.Connect()
.Filter(filter)
.Bind(out results)
.Subscribe(
x =>
{
Console.WriteLine($"Got {results.Count} results");
}));
// Those works as expected
trigger.OnNext("99999");
trigger.OnNext("9999");
trigger.OnNext("9998");
trigger.OnNext("1");
trigger.OnNext("100001");
// At this point, because there aren't any changes we don't get any more results
// until we return something other than 0 items.
trigger.OnNext("100002");
trigger.OnNext("100003");
// This will get results as expected.
trigger.OnNext("99998");
}
Этот код дает следующие результаты .. обратите внимание, что я не получаю никаких результатов для 100002 и 100003:
Searching for: 99999
Got 1 results
Searching for: 9999
Got 11 results
Searching for: 9998
Got 11 results
Searching for: 1
Got 11112 results
Searching for: 100001
Got 0 results
Searching for: 100002
Searching for: 100003
Searching for: 99998
Got 1 results
Я ожидал, что Observable сработает, даже если онс 0 изменениями, поскольку я только что запустил фильтр и, скорее всего, заинтересован в результате.
У кого-нибудь есть идеи, как обойти это?Я что-то не так делаю?