[英]How can one make a generic Blazor Component which can take in varying lists of objects as parameters?
<label for="client-list" class="label" style="display:inline">Client</label> <i class="fas fa-user-plus"></i> <br />
<input class="input field" value="@(GetClientName(@ClientID))" @oninput="@ClientSearchUpdated"/>
@if (AvailableClients != null)
{
<ul>
@foreach (var client in AvailableClients)
{
<li id="@client.Id" @onclick="@(e => SetClientID(e, client.Id))">@client.FullName</li>
}
</ul>
}
我希望能够采用上述标记/代码并将其转换为一个可重用的组件,该组件将创建一个输入字段,在输入时,将根据输入的内容显示结果列表。这些结果将属于传入的列表。例如:如果传入一个List<Person>
,它将在数据库中搜索与用户键入的搜索词匹配的人。在通用版本中,包含要搜索的对象的列表将当然,不是AvailableClients
,也不是获取/更新特定于客户端的信息的函数。
最后,我的目标是能够将上面的代码片段替换为:
<SearchableDropdown DropdownItems="AvailableClients"></SearchableDropdown>
(当前搜索的字段由当前每个 DataAccessObjects 中使用的 sproc 决定)
我在尝试开发这样一个通用组件时遇到的问题是,我一开始对泛型并不十分熟悉(我了解基本概念,使用泛型的语法是什么,等等,但我还没有创建很多通用代码),尤其是在将该概念与 Blazor 集成时。
到目前为止我尝试过的是:
List<ISearchableDropdownItem>
,并且我系统中的对象将实现此接口,该接口将有两个成员: ID
和DropdownDisplayInfo
,这将允许下拉列表发送有关单击哪个项目的信息,以及给出每个项目要为搜索结果中的每个项目显示的内容。这种方法的问题在于,我必须为 DataAccess 层和我在 Blazor 应用程序中创建的服务创建接口。 这是一个长期的级联问题,它将使我陷入界面创建的兔子洞。 我什至不能 100% 确定此解决方案最终是否有效。
@typeparam TDropdownItem
指令允许在整个组件中使用的类型是传入的类型。 这样做的明显问题是它仍然会给使用 SearchableDropdown 组件的人带来很多责任来为 RenderFragment 提供适当的降价,另外这仍然留下了具有通用性的问题,“ GetObjectName(ObjectID)
”和“ ObjectSearchUpdated
" 组件的函数。
有没有一种相当直接的方法来实现我完全缺少的? 我什至在正确的轨道上远程,它只是需要对现有代码进行大量重构才能使事情正常工作?
如果无法实现接口方法,也许您可以尝试创建一个公共代理对象来传递参数。
例如,您可以尝试使用 LINQ 将Id 、 Name和Delegate作为代理列表传递。
在 OnInitialized 或您启动它的任何地方准备您的参数。
这是一个简单的概念,展示了如何使用委托。
委托、数据和代理类初始化:
public delegate void OnClick(UIEventArgs eventArgs, int id, string name);
private class ExampleData
{
// let's assume that it has different naming convention for your case
public int IdValue {get;set;}
public string Fullname {get;set;}
}
private class SearchableDropdownItem
{
public int Id {get;set;}
public string Name {get;set;}
public OnClick OnClicked {get;set;}
}
示例代理创建:
public void Prepare()
{
var dataList = new List<ExampleData>();
for(int i=0; i<3; i++)
{
dataList.Add(new ExampleData(){
IdValue = i+1,
Fullname = "test" + (i + 1)
});
}
var searchableItemList = dataList.Select(x => new SearchableDropdownItem(){
// here is how you can set callback and fields
Id = x.IdValue,
Name = x.Fullname,
OnClicked = new OnClick(SetClientID)
}).ToList();
}
public void SetClientID(UIEventArgs eventArgs, int id, string name)
{
// implement your code
}
并将 searchableItemList 传递给组件并使用它:
<SearchableDropdown ItemList="searchableItemList"></SearchableDropdown>
...
@foreach (var item in searchableItemList)
{
<li id="@item.Id" @onclick="@(e => item.OnClicked(e,client.Id,client.Name))">@item.Name</li>
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.