Добавление класса компонента с параметром type как свойство в Blazor
Для обычного компонента вы просто объявляете компонент как частное свойство и добавляете имя в качестве параметра @type в определении компонента.
Однако, когда я добавляю компонент с параметром типа и настраиваю его, как показано ниже, код компилируется и запускается, но свойство никогда не заполняется - оно всегда равно null. См. Метод "WantToDoAnUpdate" в последнем блоке кода. Я принудительно обновляю компонент, потому что он использует разбиение на страницы и не обновляется с помощью обычных механизмов Blazor.
CardList.razor
@inherits ComponentComponentBase
@typeparam TItem
........................
create a table of values with pagination
..................
CardList.razor.cs
public partial class CardList<TItem> : ComponentComponentBase
{
......
[Parameter]
public IReadOnlyList<TItem> Items { get; set; }
......
public void UpdateList()
{
........
}
}
DeliveryList.razor
@inherits PageComponentBase
<CardList@key="this._MyComponent" TItem="dbDelivery" ....>
</CardList>
DeliveryList.razor.cs
public partial class DeliveryList<TItem> : PageComponentBase
{
......
private CardList<IReadOnlyList<dbDelivery>> _CardList { get; set; }
......
public void WantToDoAnUpdate()
{
....
--ALWAYS NULL--
if (this._CardList != null) this._CardList.UpdateList();
}
}
Я предполагаю, что неправильно объявляю _CardList.
Отлично, спасибо за ответ. Да, я настраивал список, я просто не включил это в код. Cardlist использует предоставленный список для создания страничного списка (страница x из 25 значений), в котором и возникают проблемы. Поскольку отображаемый список представляет собой новый список, полученный в процессе разбиения на страницы из Items, обновление пользовательского интерфейса не происходит, когда Items обновлено. Вызов UpdateList из родительского элемента перенаправляет страничный список и должен запускать обновление производного списка и обновление пользовательского интерфейса.
Однако, поскольку я не мог заставить его работать, я начал копаться в основном коде Blazor на Github, чтобы увидеть, как это делают разработчики Blazor. Теперь я решил проблему другим способом, используя обработчики событий в службе логического уровня, которая содержит список, без необходимости выполнять вызовы из родительского элемента в дочерний, чтобы вызвать обновление. Я также использовал обработчики событий, запускаемые из набора в свойстве, в других случаях, таких как пользовательские элементы управления вводом / отображением.
В любом случае, еще раз спасибо, что нашли время ответить.
1 ответ
Надеюсь, это даст вам то, что вам нужно. Я вижу две вещи, которые, как мне кажется, работают против вас.
Во-первых, в частичном классе Cardlist у вас есть список, украшенный[Parameter]
атрибут, но вы никогда не устанавливаете параметр из вызывающего кода. Вам нужно будет установить ОБЕИХTItem
и Items
параметры, чтобы это работало правильно, поэтому список карточек знает, какой тип содержит список, и где найти список. Помните, что в C# списки являются ссылочным типом, поэтомуItems
вы устанавливаете фактически просто ссылку на любой список, который вы предоставляете, а не сам список в новой форме или новый список в целом. Итак, ваш DeliveryList должен иметь что-то вроде свойства списка, показанного ниже:
public partial class DeliveryList : PageComponentBase
{
......
private <IReadOnlyList<dbDelivery>> CardListContents { get; set; }
......
}
Затем в DeliveryList.razor вы передадите ссылку на список компоненту Cardlist следующим образом:
<CardList @key="this._MyComponent" TItem="dbDelivery" Items="@CardListContents" ....>
</CardList>
Теперь компонент Cardlist становится инструментом визуализации для внешнего списка универсального типа.
Во-вторых, есть некоторая двусмысленность в том, чтоUpdateList
предполагается, но я предполагаю, что вы подключаете кнопку, которая будет вызывать обновление списка при нажатии. Для этого вы можете использовать обратный вызов события в Cardlist.
Ваш Cardlist.razor теперь становится:
@inherits ComponentComponentBase
@typeparam TItem
........................
create a table of values with pagination
..................
<button @onclick="OnUpdateButtonClickedCallBack">Update List</button>
И ваш Cardlist.razor.cs станет:
public partial class CardList<TItem> : ComponentComponentBase
{
......
[Parameter]
public IReadOnlyList<TItem> Items { get; set; }
......
[Parameter]
public EventCallBack OnUpdateButtonClickedCallBack { get; set;}
}
Теперь вы настроены так, чтобы указывать на внешний метод, который будет выполняться при каждом нажатии кнопки "Обновить список".
Затем вам нужно подключить метод в своем DeliveryList.razor.cs, и мы сможем использовать ваш WantToUpdateList
метод:
public partial class DeliveryList : PageComponentBase
{
......
private <IReadOnlyList<dbDelivery>> CardListContents { get; set; }
private WantToUpdateList()
{
//Since the list is read only you need to generate a new one
//or call a method from elsewhere that returns a new one,
//change the method below to suit your needs
CardListContents = new IReadOnlylist<dbDelivery>();
}
......
}
Теперь вы можете указать на этот метод с помощью EventCallback, который вы настроили при объявлении Cardlist. Обратите внимание, что конфигурация становится довольно длинной, поэтому я разбил ее на несколько строк:
<CardList @key="this._MyComponent"
OnUpdateButtonClickedCallBack="@WantToUpdateList" //Sets the callback function
TItem="dbDelivery" //Sets the type
Items="@CardListContents" ....> //Points to the list
</CardList>
Теперь вы можете использовать <Cardlist>
компонент с любым списком только для чтения, указав тип, список и функцию обратного вызова, с которой будет работать. Cardlist становится независимым инструментом визуализации, и все состояния, логика и функции для списка находятся в одном месте внутри вызывающего компонента, что делает<CardList>
действительно универсальный и портативный. В этом примере любые обновления в списке должны быть получены движком Blazor и инициировать повторный рендеринг, но если нет, вы можете добавить вызов кStateHasChanged();
в качестве последней строки вашего метода обновления в вызывающем коде, и вы должны работать.
Однако обратите внимание, что это решение еще не завершено, так как вам, вероятно, придется добавить несколько RenderFragment
логика в Cardlist
чтобы указать, как вы хотите визуализировать свою таблицу.
Документация.NET Core отлично справляется с этой задачей.Похоже, вы уже видели это, поскольку стиль кода выглядит одинаково, и не включили его здесь для ясности.
Надеюсь это поможет!