Немного сложно следовать, поскольку есть некоторые внешние методы, которые вы не показали в этом примере (возможно, отредактируйте для ясности?), Но похоже, что вы используете что-то вне вашего Pager.razor диктовать, как работает ваш пейджинг. Дешевая распродажа - обратный вызов события DisplayChanged
. Я могу предложить вам решить эту проблему, разобрав проблемы, и вы можете заставить все работать. (Я смог довольно быстро запустить его, работая с тем, что у вас есть)
Во-первых, давайте настроим пейджер, поэтому все, что он делает, это обрабатывает информацию на странице, и он содержит все свои собственные логи c сделать это в автономном, многократно используемом компоненте. дайте ему список TItem
и RenderFragment<TItem>
, и он знает, что делать.
@typeparam TItem
<div class="row d-flex col-9">
<div class="justify-content-center">
@if (List != null)
{
@foreach (var item in DisplayList)
{
@ChildContent(item)
}
}
@if (PageCount > 1 && List.Count > PageSize)
{
...Nothing here was changed, eliminated for brevity...
}
</div>
<select class="custom-select offset-1 col-1 ml-auto" bind="@PageSize" @onchange="@(e => ChangePageSize(e))">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
</select>
</div>
@code {
[Parameter]
public List<TItem> List { get; set; }
public List<TItem> DisplayList { get; set; } = new List<TItem>();
[Parameter]
public RenderFragment<TItem> ChildContent { get; set; }
//[Parameter]
//public Action<List<TItem>> DisplayChanged { get; set; }
//[Parameter]
//public Action<bool> Rendered { get; set; }
private int PageSize { get; set; } = 10;
private int CurrentPage { get; set; } = 1;
private int StartIndex { get; set; }
private int FinishIndex { get; set; }
private int PageCount { get; set; }
//protected override void OnAfterRender(bool firstRender)
//{
// base.OnAfterRender(firstRender);
// Rendered?.Invoke(true);
//}
private void ChangePageSize(ChangeEventArgs e)
{
PageSize = int.Parse(e.Value.ToString());
ChangePage(1);
}
private void ChangeDisplay()
{
DisplayList = List
.Skip((CurrentPage -1) * PageSize)
.Take(PageSize)
.ToList();
}
protected override void OnParametersSet()
{
// Edited
ChangePage(1);
}
protected void ChangePage(int page)
{
CurrentPage = page;
ResetIndex();
ChangeDisplay();
}
private void ResetIndex()
{
PageCount = List.Count / PageSize;
if (List.Count % PageSize > 0)
{
PageCount++;
}
StartIndex = Math.Max(CurrentPage - 5, 1);
FinishIndex = Math.Min(CurrentPage + 5, PageCount);
}
}
Вы увидите, что несколько вещей в блоке @code закомментированы. Вам не нужно это, чтобы заставить это работать. Мы обработаем значения в начальном списке через минуту в родительском компоненте. Вы увидите параметр RenderFragment<TItem>
и новое свойство для DisplayList
, которое НЕ является параметром. Вы также заметите в разметке, что у нас есть блок @foreach
, отображающий экземпляр нашего RenderFragment
для каждого элемента в свойстве DisplayList
. Если вы будете следовать логике c из метода OnParametersSet
и вашим обработчикам для нажатия номеров страниц и стрелок, вы увидите, что мы создаем и отображаем подсписок нашего параметра List
на основе количества страниц и номер страницы, и это все, что отображается. Этот компонент теперь отвечает за подкачку элементов из списка, который он дал, и у него нет внешних зависимостей для запуска, кроме списка для отображения, и инструкций о том, как отображать каждый элемент в виде RenderFragment<TItem>
.
Далее, в компоненте Parent мы настраиваем вызов на пейджер следующим образом:
<Pager TItem="User" List="FilteredUsers">
<h6>@context.FirstName @context.LastName is in @context.Role </h6>
</Pager>
Вы можете настроить это так, как хотите, я использовал <h6>
теги для иллюстрации, но следуйте указаниям здесь , если вам нужно больше глубины, создание таблиц, списков и т. д. c. Этот компонент теперь принимает дочерний контент между тегами <Pager>
и отображает 1 для каждого элемента в своем собственном перемещаемом списке.
Пока что мы отделили логику пейджера c от остальной части страницы, так что теперь это только инструмент рендеринга, а логика пейджинга c является внутренней. Теперь мы можем сосредоточиться на фильтрации и забыть о подкачке.
Фильтрация поиска: Во-первых, я установил начальное значение для поиска "Свойство" и установил вспомогательное поле следующим образом:
private string property = "FirstName";
private string Property
{
get => property;
set
{
property = value;
Filter();
}
}
Теперь оно выравнивается по начальное значение раскрывающегося списка, поскольку <select>
обновляет его только при изменении, а также обновляет результаты поиска при изменении раскрывающегося списка.
Я оставил вашу собственность SearchTerm
, как у вас.
Теперь в методе Filter:
private void Filter()
{
if (string.IsNullOrEmpty(SearchTerm))
{
FilteredUsers = Users;
}
else
{
switch (Property)
{
case "FirstName":
FilteredUsers = Users.Where(u => u.FirstName.ToLower().Contains(SearchTerm.ToLower())).ToList();
break;
case "LastName":
FilteredUsers = Users.Where(u => u.LastName.ToLower().Contains(SearchTerm.ToLower())).ToList();
break;
case "Role":
FilteredUsers = Users.Where(u => u.Role.ToString().ToLower().Contains(SearchTerm.ToLower())).ToList();
break;
case "Property":
FilteredUsers = Users.Where(u => u.Role.ToString().ToLower().Contains(SearchTerm.ToLower())).ToList();
//FilteredUsers = Users.Where(u => TicketingRosters.Any(t => t.Property.PropertyName.ToLower().Contains(SearchTerm.ToLower()) && u.UserId == t.SellerId)).ToList();
break;
default:
FilteredUsers = Users;
break;
}
}
StateHasChanged();
}
Теперь он сначала проверяет значение поиска и возвращает полный список Users
, если он пуст. Если нет, то вы вводите переключатель. Все дела работают так, как у меня, но вы увидите, что я прокомментировал Where
logi c, который вы имели изначально. Честно говоря, TicketingRosters мне не знаком, и я могу сказать, что ваша логика c находится в домене, о котором я ничего не знаю, так что вам придется самостоятельно рассуждать об этом последнем случае. НО, если все остальное работает, теперь у вас есть целенаправленный подход к тому, где найти вашу ошибку.
Итак, теперь метод Filter устанавливает отфильтрованный список, пейджер берет весь этот список и обрабатывает пейджинг самостоятельно, и у вас есть красиво разделенные проблемы, поэтому, если у вас есть проблема, вы знаете, где искать. Не правильно пейджинг -> это в пейджере. Неправильная фильтрация -> это в логи фильтра c.
Редактировать
После того как ОП добавил определения классов TicketingRoster
и UserDto
, я допустил ошибку, думая, что нашел проблему в запросе. Тем не менее, через некоторые операции OP выяснилось, что Pager
, который я описал выше, все еще не функционировал совершенно правильно, и запросы были, и после другого взгляда я очистил метод OnParametersSet
для вызова ChnagePage(1)
, что оба сбрасывают текущую страницу на 1 и сбрасывают количество страниц. Тест на моей стороне подтвердил, что проблема ОП с моим первоначальным ответом была устранена.
Мое первое редактирование содержало довольно много информации о структуре и теории запросов, и я удалил этот раздел, потому что а) он больше не имеет отношения к этому обсуждению, и б) оглядываясь назад, он может показаться снисходительным хотя это никогда не было моим намерением в любой момент.