Как передать параметр компоненту перед рендерингом?

#blazor #blazor-server-side #blazor-component

#блейзор #blazor-серверная часть #блейзор-компонент

Вопрос:

Я пытаюсь создать простую таблицу с разбиением на страницы на стороне сервера Blazor.

Таблица является компонентом Blazor, а модуль разбиения на страницы-еще одним компонентом Blazor. Компонент разбиения на страницы ( Paginador ) имеет параметр для общего количества строк (который используется для вычисления последней страницы в наборе).

Я могу отобразить таблицу, раздел разбиения на страницы, и он обновляет содержимое таблицы при изменении страницы, но по какой-то причине TotalRows параметр получает значение Paginador 0 вместо общего значения строк.

Код выглядит следующим образом.

Компонент списка:

 @page "/personas/listar"  @inject SqlServerPersonasRepository _repo;  lt;h3gt;Lista de personaslt;/h3gt;  lt;table class="table table-striped"gt;  lt;theadgt;  lt;trgt;  lt;thgt;DNIlt;/thgt;  lt;thgt;Nombrelt;/thgt;  lt;thgt;Apellidolt;/thgt;  lt;thgt;Fecha de nacimientolt;/thgt;  lt;thgt;¿Activo?lt;/thgt;  lt;thgt;Tipolt;/thgt;  lt;/trgt;  lt;/theadgt;  lt;tbodygt;  @foreach (var item in _personas)  {  lt;trgt;  lt;tdgt;lt;codegt;@item.Dnilt;/codegt;lt;/tdgt;  lt;tdgt;@item.Nombrelt;/tdgt;  lt;tdgt;@item.Apellidolt;/tdgt;  lt;tdgt;@item.FechaNacimiento.ToString("dd/MM/yyyy")lt;/tdgt;  lt;tdgt;@(item.Activo ? "Sí":"No")lt;/tdgt;  lt;tdgt;@item.Tipo.Nombrelt;/tdgt;  lt;/trgt;  }  lt;/tbodygt; lt;/tablegt;  lt;div class="row"gt;  lt;Paginador TotalRows="_total_rows" OnPageChange="@GetPageAsync" /gt; lt;/divgt;  @code {  [Parameter]  public int Page { get; set; } = 1;   private int _total_rows;  private Listlt;PersonaModelgt; _personas = new();   protected override async Task OnInitializedAsync()  {  _total_rows = await _repo.ContarAsync();  }   protected override async Task OnParametersSetAsync()  {  _personas = await _repo.ListarAsync(Page);  }   public async Task GetPageAsync(int page)  {  _personas = await _repo.ListarAsync(page);  } }  

Paginador :

 @inject IOptionslt;TablesSettingsgt; Options  lt;nav aria-label="Page navigation example"gt;  lt;ul class="pagination"gt;  lt;li class="page-item @(_current_page == 1 ? "disabled": string.Empty)"gt;  lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(1))" aria-label="Previous"gt;  lt;span aria-hidden="true"gt;amp;laquo;lt;/spangt;  @*lt;span class="sr-only"gt;1lt;/spangt;*@  lt;/buttongt;  lt;/ligt;  @if (_current_page == 1)  {  lt;li class="page-item disabled"gt;lt;button type="button" class="page-link"gt;1lt;/buttongt;lt;/ligt;  lt;li class="page-item"gt;lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(2))"gt;2lt;/buttongt;lt;/ligt;  lt;li class="page-item"gt;lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(3))"gt;3lt;/buttongt;lt;/ligt;  }  else if (_current_page == _last_page)  {  var two_to_last = _last_page - 2;  var one_to_last = _last_page - 1;  lt;li class="page-item"gt;lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(two_to_last))"gt;@two_to_lastlt;/buttongt;lt;/ligt;  lt;li class="page-item"gt;lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(one_to_last))"gt;@one_to_lastlt;/buttongt;lt;/ligt;  lt;li class="page-item disabled"gt;lt;button type="button" class="page-link"gt;@_last_pagelt;/buttongt;lt;/ligt;  }  else  {  var previous = _current_page - 1;  var next = _current_page   1;  lt;li class="page-item"gt;lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(previous))"gt;@previouslt;/buttongt;lt;/ligt;  lt;li class="page-item"gt;lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(_current_page))"gt;@_current_pagelt;/buttongt;lt;/ligt;  lt;li class="page-item"gt;lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(next))"gt;@nextlt;/buttongt;lt;/ligt;  }   lt;li class="page-item @(_current_page == _last_page ? "disabled" : string.Empty)"gt;  lt;button type="button" class="page-link" @onclick="(async () =gt; await PageChangeAsync(_last_page))" aria-label="Next"gt;  lt;span aria-hidden="true"gt;amp;raquo;lt;/spangt;  @*lt;span class="sr-only"gt;@_last_page_indexlt;/spangt;*@  lt;/buttongt;  lt;/ligt;  lt;/ulgt; lt;/navgt;  @code {  [Parameter]  public int TotalRows { get; set; }  [Parameter]  public EventCallbacklt;intgt; OnPageChange { get; set; }   private int _current_page { get; set; } = 1;  private int _last_page;   protected override async Task OnInitializedAsync()  {  _last_page = (int)Math.Ceiling(decimal.Divide(TotalRows, Options.Value.RowsPerPage));  }   protected async Task PageChangeAsync(int page)  {  await OnPageChange.InvokeAsync(page);  _current_page = page;  StateHasChanged();  } }  

Что я выяснил, так это то, что при загрузке страницы Paginador она отображается до OnInitializedAsync вызова метода компонента списка, поэтому TotalRows параметр принимает значение по умолчанию.

Итак, как мне получить общее количество строк Paginador до того, как они будут отрисованы?

Заранее спасибо.

Комментарии:

1. Поместите @if блок вокруг компонента, ожидающего данных.

2. @BrianParker, который сделал это. Комментарий Хенка стал последним кусочком головоломки. Спасибо.

Ответ №1:

Итак, как мне получить общее количество строк в Paginador до его отображения?

Put an @if block around the component expecting the data. – Brian Parker

Сделайте что-нибудь вроде этого:

 if (_total_rows gt; 0 ) {  lt;div class="row"gt;  lt;Paginador TotalRows="_total_rows" OnPageChange="@GetPageAsync" /gt;  lt;/divgt; }  

Оператор if теперь позволит создавать компонент Paginador, если общее количество строк больше 0.

Примечание: Я очень быстро прочитал ваш вопрос, но я считаю, что это то, что вам следует сделать:

 protected override async Task OnInitializedAsync() {  // Retrieve the persons list  _personas = await _repo.ListarAsync(Page);    }  // Get rid of OnParametersSetAsync()  

И

 lt;div class="row"gt;  lt;Paginador TotalRows="@_personas.Count" OnPageChange="@GetPageAsync" /gt; lt;/divgt;  

Комментарии:

1. И да, и нет. «Да», потому что я не знал Paginador , что оно отображается более одного раза, поэтому окружение его @if , как вы выразились, сделало свое дело; большое вам спасибо. И нет, потому что каждый вызов _repo.ListarAsync(int) приносит не более 15 строк (как указано TablesSettings ), поэтому ввод этой суммы TotalRows оставил бы меня без страниц.