【问题标题】:Create an InputSelect component that accepts lists with Blazor使用 Blazor 创建一个接受列表的 InputSelect 组件
【发布时间】:2021-03-07 04:06:29
【问题描述】:

使用 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 输入选择 //或者添加另一个类型参数@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 用于绑定。

【问题讨论】:

    标签: c# asp.net-core blazor blazor-webassembly


    【解决方案1】:

    我之前已经构建并使用过这个

    @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;
     } 
    

    【讨论】:

    • 很不错的方法,可以继承InputBase吗?
    猜你喜欢
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 2023-02-23
    • 2018-01-06
    • 2018-09-23
    • 2018-03-06
    相关资源
    最近更新 更多