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



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

<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用于组件,一个用于值,一个用作列表项。它似乎也不支持它。

    @继承InputSelect//或添加另一个typeparam@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;
} 

相关内容

  • 没有找到相关文章