繁体   English   中英

使用 Blazor 创建一个接受列表的 InputSelect 组件

[英]Create an InputSelect component that accepts lists with Blazor

使用 Blazor InputSelect您可以遍历组件ChildContent中的列表项,但是
我想创建一个自定义 Blazor(WebAssembly 版本 5) InputSelect ,它可以接受要在选择中呈现的任何对象的列表,代码可能如下所示:

<CustomInputSelect @bind-Value="@myEntity.CountryId" For="@(()=> myEntity.CountryId)" List="countries"
 ValueField="@(a => a.Id)" DisplayField="@(a => a.CountryName)" ></CustomInputSelect>

甚至这个:

<CustomInputSelect @bind-Value="@myEntity.Country" For="@(()=> myEntity.Country)" List="countries"
 ValueField="Id" DisplayField="CountryName" ></CustomInputSelect>

注:我用了For属性的帮助编译器推断类型CountryId ,也为验证这是。 @typeparam的组件。)

我尝试了很多方法,但没有一个奏效,所以我在下面解释它们:

  • 我尝试对列表使用dynamic类型,但似乎 Blazor 不支持动态类型,因为 razor 生成的代码中存在错误。

  • 我尝试对组件使用多个@typeparam ,一个用于值,一个用于列表项。 而且它似乎也不支持它。

    @inherits InputSelect //或添加另一个类型参数@typeparam TListItem

  <select>
                @foreach (var item in List)
                {
                   < option value="???">???</option >
                }
    </select> 
    
    @code{
     [Parameter] public Expression<Func<TValue>>? For { get; set; }
     [Parameter] public List<dynamic> List { get; set; }// or List<TListItem> 
     [Parameter] public Expression<Func<TListItem>>? ValueField { get; set; }
     [Parameter] public Expression<Func<string>>? DisplayField { get; set; }
    
    }

我的目标是将任何类型的列表发送到InputSelect@typeparam用于绑定。

我以前构建并使用过这个

@typeparam TItem
  <div class="form-control-wrapper">

    <select class="form-control-label" @onchange="ChangeHandler">
        @if (ShowDefaultOption)
        {
            <option value="0" hidden disabled>- Please Select -</option>
        }
        @foreach (var (id, item) in idDictionary)
        {
            <option value="@id">@Selector(item).ToString()</option>
        }
      </select>
    </div>
@code {

[Parameter] public IList<TItem> Items { get; set; }
[Parameter] public Func<TItem, object> Selector { get; set; }
[Parameter] public EventCallback<TItem> ValueChanged { get; set; }
[Parameter] public bool ShowDefaultOption { get; set; } = true;

private Dictionary<Guid, TItem> idDictionary;

protected override void OnInitialized()
{
    idDictionary = new Dictionary<Guid, TItem>();
    Items.ToList().ForEach(x => idDictionary.Add(Guid.NewGuid(), x));
}

private async Task ChangeHandler(ChangeEventArgs args)
{
    if (idDictionary.TryGetValue(Guid.Parse(args.Value.ToString()), out var selectedItem))
    {
        await ValueChanged.InvokeAsync(selectedItem);
    }
}
}

然后使用可以像这样使用它:

<MySelect ValueChanged="handleStringChange" TItem="string" Items="stringItems" Selector="(x => x)" />b
<p>@_selectedStringItem</p>


@code {

IList<string> stringItems = new List<string>()
{
    "Random",
    "String",
    "Content",
    "ForDemo"
};

string _selectedStringItem;
void handleStringChange(string value) => _selectedStringItem = value;
}

或者使用一个对象:

<MySelect ValueChanged="handleChange" TItem="Person" Items="items" Selector="(x => x.Firstname)" />

@if (_selectedItem is object)
{
    <p>Selected person: Name: @_selectedItem.Firstname, Age: @_selectedItem.Age</p>
}

@code {
    class Person
    {
        public string Firstname { get; set; }
        public int Age { get; set; }
    }

    IList<Person> items = new List<Person>
    {
        new Person {Firstname = "John Doe", Age = 26},
        new Person {Firstname = "Jane Doe", Age = 23}
    };

    Person _selectedItem;

    void handleChange(Person value) => _selectedItem = value;
 } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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