使用 select 元素时如何通过 @change="" 发送对象(而不是发送值)
How to send an object through @change="" (instead of sending value) when using select element
Blazor 新手,我有一个简单的问题
在我的 Blazor 应用中,我有一个简单的 select 元素:
<select class="form-select" aria-label="Default select example" @onchange="ItemSelected">
<option selected>Open this select menu</option>
@foreach(var item in Items)
{
<option value="@item.Id"> @item.Name </option>
}
</select>
想法是当用户select有一个选项时,我想获取对象而不是密钥,这里是函数:
List<object> ItemContainer = new List<object>();
private void ItemSelected(ChangeEventArgs obj) {
...
ItemContainer.Add(obj);
}
如何捕获对象?
你不能直接。 ChangeEventArgs
returns 字符串,因为它是 Value
对象。
你需要做这样的事情:
@page "/"
<select @onchange=OnSelect >
@foreach (var country in Countries)
{
<option value="@country.Id" selected="@this.IsSelected(country)">@country.Name</option>
}
</select>
<div>
Selected : @this.SelectedCountry
</div>
@code {
private Country? country;
private string SelectedCountry => this.country?.Name ?? "None Selected";
protected override void OnInitialized()
{
// to demo selected is working
this.country = this.Countries[1];
}
private void OnSelect(ChangeEventArgs e)
{
if (int.TryParse(e.Value?.ToString(), out int value))
country = Countries.SingleOrDefault(item => item.Id == value);
}
private bool IsSelected(Country c)
=> c == this.country;
public List<Country> Countries = new List<Country>
{
new Country { Id =44, Name = "UK" },
new Country { Id =61, Name = "France" },
new Country { Id =1, Name = "USA" },
};
public class Country
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
}
@page "/"
<select @onchange="ItemSelected" class="form-select">
<option value="null">Select...</option>
@foreach (var option in options)
{
<option @key="option" value="@option.ID">@option.Value</option>
}
</select>
@code {
private Option option;
private List<Option> options = Enumerable.Range(1, 10).Select(i => new Option { ID = i, Value = $"Option{i}" }).ToList();
private void ItemSelected(ChangeEventArgs args)
{
if (int.TryParse(args.Value.ToString(), out int selectedID))
{
option = options.Where(o => o.ID == selectedID).FirstOrDefault();
Console.WriteLine(option.ID.ToString());
Console.WriteLine(option.Value);
}
}
public class Option
{
#nullable enable
public int? ID { get; set; }
#nullable disable
public string Value { get; set; }
}
}
更新:
Hi, sorry for bothering you but I am stuck a bit on something. How do I avoid Option in my code? Because I already have an Item class private IEnumerable Items { get; set; } = new List(); is there a way to substitute both? thanks
Option
是我给的class名字。你可以给它任何你想要的名字。您可以像下面这样定义 class:
public class ItemDTO
{
#nullable enable
public int? Id { get; set; }
#nullable disable
public string Name{ get; set; }
}
注意:如果您使用的是 .Net 6.0,则可以删除 #nullable 指令
更新:
不要使用 Task.Run
改变这个:
protected override async Task OnInitializedAsync()
{
await Task.Run(GetItems);
Client = _client.Get(Id);
}
private void GetItems()
{
Items = _item.GetAll();
}
收件人:
protected override void OnInitialized()
{
Client = _client.Get(Id);
Items = _item.GetAll();
}
改变这个:
private IEnumerable<ItemDTO> Items { get; set; } = new List<ItemDTO>();
收件人:
private IList<ItemDTO> Items { get; set; } = new List<ItemDTO>();
以上更改与其说是功能性的,不如说是装饰性的。我无法验证这一点,因为我只阅读了代码;我没有在 IDE.
中查看和 运行 它
无论如何,以下代码片段是不正确的,因此会导致错误:
var option = ItemDTO.Where(o => o.Id ==
selectedID).FirstOrDefault();
上面的代码假设查询的是ItemDTO对象列表,return单个对象,其Id属性等于我们传递给方法(ItemSelected)的值,其中代码被执行。定义为 Items
的 ItemDTO 对象列表应用于搜索所选项目;也就是说,您应该使用:
`Items.Where`
而不是:
ItemDTO.Where
ItemDTO
是 class 名称或类型...
您的代码应该是这样的:
var option = Items.Where(o => o.Id ==
selectedID).FirstOrDefault();
愿上帝保佑您的代码;}
抱歉,我现在打字不好,无法准确检查语法,但可能是这样的:
@onchange="(e)=> ItemSelected(Items.Single(i=> i.ID.ToString() == e.Value.ToString()))"
然后
private void ItemSelected(YourItemClass SelectedItem) {}
Blazor 新手,我有一个简单的问题
在我的 Blazor 应用中,我有一个简单的 select 元素:
<select class="form-select" aria-label="Default select example" @onchange="ItemSelected">
<option selected>Open this select menu</option>
@foreach(var item in Items)
{
<option value="@item.Id"> @item.Name </option>
}
</select>
想法是当用户select有一个选项时,我想获取对象而不是密钥,这里是函数:
List<object> ItemContainer = new List<object>();
private void ItemSelected(ChangeEventArgs obj) {
...
ItemContainer.Add(obj);
}
如何捕获对象?
你不能直接。 ChangeEventArgs
returns 字符串,因为它是 Value
对象。
你需要做这样的事情:
@page "/"
<select @onchange=OnSelect >
@foreach (var country in Countries)
{
<option value="@country.Id" selected="@this.IsSelected(country)">@country.Name</option>
}
</select>
<div>
Selected : @this.SelectedCountry
</div>
@code {
private Country? country;
private string SelectedCountry => this.country?.Name ?? "None Selected";
protected override void OnInitialized()
{
// to demo selected is working
this.country = this.Countries[1];
}
private void OnSelect(ChangeEventArgs e)
{
if (int.TryParse(e.Value?.ToString(), out int value))
country = Countries.SingleOrDefault(item => item.Id == value);
}
private bool IsSelected(Country c)
=> c == this.country;
public List<Country> Countries = new List<Country>
{
new Country { Id =44, Name = "UK" },
new Country { Id =61, Name = "France" },
new Country { Id =1, Name = "USA" },
};
public class Country
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
}
@page "/"
<select @onchange="ItemSelected" class="form-select">
<option value="null">Select...</option>
@foreach (var option in options)
{
<option @key="option" value="@option.ID">@option.Value</option>
}
</select>
@code {
private Option option;
private List<Option> options = Enumerable.Range(1, 10).Select(i => new Option { ID = i, Value = $"Option{i}" }).ToList();
private void ItemSelected(ChangeEventArgs args)
{
if (int.TryParse(args.Value.ToString(), out int selectedID))
{
option = options.Where(o => o.ID == selectedID).FirstOrDefault();
Console.WriteLine(option.ID.ToString());
Console.WriteLine(option.Value);
}
}
public class Option
{
#nullable enable
public int? ID { get; set; }
#nullable disable
public string Value { get; set; }
}
}
更新:
Hi, sorry for bothering you but I am stuck a bit on something. How do I avoid Option in my code? Because I already have an Item class private IEnumerable Items { get; set; } = new List(); is there a way to substitute both? thanks
Option
是我给的class名字。你可以给它任何你想要的名字。您可以像下面这样定义 class:
public class ItemDTO
{
#nullable enable
public int? Id { get; set; }
#nullable disable
public string Name{ get; set; }
}
注意:如果您使用的是 .Net 6.0,则可以删除 #nullable 指令
更新:
不要使用 Task.Run
改变这个:
protected override async Task OnInitializedAsync()
{
await Task.Run(GetItems);
Client = _client.Get(Id);
}
private void GetItems()
{
Items = _item.GetAll();
}
收件人:
protected override void OnInitialized()
{
Client = _client.Get(Id);
Items = _item.GetAll();
}
改变这个:
private IEnumerable<ItemDTO> Items { get; set; } = new List<ItemDTO>();
收件人:
private IList<ItemDTO> Items { get; set; } = new List<ItemDTO>();
以上更改与其说是功能性的,不如说是装饰性的。我无法验证这一点,因为我只阅读了代码;我没有在 IDE.
中查看和 运行 它无论如何,以下代码片段是不正确的,因此会导致错误:
var option = ItemDTO.Where(o => o.Id ==
selectedID).FirstOrDefault();
上面的代码假设查询的是ItemDTO对象列表,return单个对象,其Id属性等于我们传递给方法(ItemSelected)的值,其中代码被执行。定义为 Items
的 ItemDTO 对象列表应用于搜索所选项目;也就是说,您应该使用:
`Items.Where`
而不是:
ItemDTO.Where
ItemDTO
是 class 名称或类型...
您的代码应该是这样的:
var option = Items.Where(o => o.Id ==
selectedID).FirstOrDefault();
愿上帝保佑您的代码;}
抱歉,我现在打字不好,无法准确检查语法,但可能是这样的:
@onchange="(e)=> ItemSelected(Items.Single(i=> i.ID.ToString() == e.Value.ToString()))"
然后
private void ItemSelected(YourItemClass SelectedItem) {}