繁体   English   中英

如何制作一个通用的 Blazor 组件,它可以将不同的对象列表作为参数?

[英]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 集成时。

到目前为止我尝试过的是:

  1. 使用继承来接受通用List<ISearchableDropdownItem> ,并且我系统中的对象将实现此接口,该接口将有两个成员: IDDropdownDisplayInfo ,这将允许下拉列表发送有关单击哪个项目的信息,以及给出每个项目要为搜索结果中的每个项目显示的内容。

这种方法的问题在于,我必须为 DataAccess 层和我在 Blazor 应用程序中创建的服务创建接口。 这是一个长期的级联问题,它将使我陷入界面创建的兔子洞。 我什至不能 100% 确定此解决方案最终是否有效。

  1. 使用@typeparam TDropdownItem指令允许在整个组件中使用的类型是传入的类型。

这样做的明显问题是它仍然会给使用 SearchableDropdown 组件的人带来很多责任来为 RenderFragment 提供适当的降价,另外这仍然留下了具有通用性的问题,“ GetObjectName(ObjectID) ”和“ ObjectSearchUpdated " 组件的函数。

有没有一种相当直接的方法来实现我完全缺少的? 我什至在正确的轨道上远程,它只是需要对现有代码进行大量重构才能使事情正常工作?

如果无法实现接口方法,也许您可​​以尝试创建一个公共代理对象来传递参数。

例如,您可以尝试使用 LINQ 将IdNameDelegate作为代理列表传递。

在 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM