【发布时间】:2020-04-18 23:19:00
【问题描述】:
<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>,它将在数据库中搜索与用户输入的搜索词相匹配的人。在通用版本中,包含对象的列表searched 不会是 AvailableClients,当然也不会是获取/更新特定于客户的信息的函数。
最后,我的目标是能够将上面的代码片段替换为:
<SearchableDropdown DropdownItems="AvailableClients"></SearchableDropdown>
(搜索的字段当前由当前每个DataAccessObjects中使用的sproc确定)
我在尝试开发这样一个泛型组件时遇到的问题是我对泛型并不是很熟悉(我了解基本概念,使用泛型的语法是什么等等,但我没有没有创建很多通用代码),尤其是在将该概念与 Blazor 集成时。
到目前为止我尝试过的是:
- 使用继承来接受通用
List<ISearchableDropdownItem>,我系统中的对象将实现这个接口,它有两个成员:ID和DropdownDisplayInfo,这将允许下拉列表发送有关哪个项目的信息点击,并为每个项目在搜索结果中显示每个项目。
这种方法的问题是我必须为 DataAccess 层和我在 Blazor 应用程序中创建的服务创建接口。这是一个冗长的级联问题,会导致我陷入界面创建兔子洞。我什至不能 100% 确定这个解决方案最终能否奏效。
- 使用
@typeparam TDropdownItem指令允许在整个组件中使用的类型是传入的类型。
这样做的明显问题是,它仍然会让使用 SearchableDropdown 组件为 RenderFragment 提供适当降价的人承担很多责任,而且仍然存在泛型问题,“GetObjectName(ObjectID)”和组件的“ObjectSearchUpdated”函数。
有没有一种我完全想念的相当直接的方法来实现这一点?我是不是走在了正确的轨道上,并且只需要对现有代码进行大量重构才能使事情正常运行?
【问题讨论】:
-
我能想象的是让
ID和DropdownDisplayInfo属性的名称像<SearchableDropdown DropdownItems="AvailableClients" IdProperty="ID"></SearchableDropdown>一样可配置。我不确定这是否使它更可重用。 -
这仍然存在函数获取适当数据的问题。我也可以将这些 EventCallbacks 传递给组件,但我再次觉得这部分地使首先拥有组件的观点无效。
标签: c# generics components fragment blazor