[英]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.