模型属性未绑定到 Blazor 中的下拉列表
Model properties not bind to dropdowns in Blazor
我有 2 个级联下拉菜单:
问题是当我点击 Save
按钮时我的模型会是空的。我无法在下拉菜单中使用 bind-value
,因为我无法使用 onchange
事件。只要绑定属性,我怎么能有级联特性呢
代码:
@using Model
<select value="@MyLocation.CountryCode" @onchange="@CountryChanged">
@if (string.IsNullOrEmpty(MyLocation.CountryCode) == true)
{
<option value="0" selected>[Choose One...]</option>
}
@foreach (var item in Countries)
{
<option value="@item.Key">@item.Value</option>
}
</select>
<br />
<select value="@MyLocation.CityCode">
@foreach (var item in CountryCities)
{
<option value="@item.Key">@item.Value</option>
}
</select>
<br />
<button class="btn btn-success" @onclick="() => HandleSave()">Save</button>
@code {
public Location MyLocation { get; set; } = new Location();
private Dictionary<string, string> Countries { set; get; } = new Dictionary<string, string>();
private Dictionary<string, string> CountryCities { set; get; } = new Dictionary<string, string>();
protected override Task OnInitializedAsync()
{
Countries.Add("01", "Germany");
Countries.Add("02", "Japan");
Countries.Add("03", "England");
return base.OnInitializedAsync();
}
private async Task CountryChanged(ChangeEventArgs e)
{
CountryCities.Clear();
switch (e.Value.ToString())
{
case "01":
CountryCities.Add("001", "Munchen");
break;
case "02":
CountryCities.Add("002", "Tokyo");
break;
case "03":
CountryCities.Add("003", "Manchester");
break;
}
}
private void HandleSave()
{
var Country = MyLocation.CountryCode; <--- CountryCode is null
}
}
您可以在 CountryChanged 方法中添加:
MyLocation.CountryCode = e.Value.ToString();
您可以对城市代码执行相同的操作:
<select value="@MyLocation.CityCode" @onchange="@OnCityChanged">
@foreach (var item in CountryCities)
{
<option value="@item.Key">@item.Value</option>
}
@code {
private void OnCityChanged(ChangeEventArgs e) => MyLocation.CityCode = e.Value.ToString();
}
编辑:请注意,要使 OnCityChanged 起作用,用户实际上必须 select 一个值。如果他们不这样做,第一个值(在您的情况下为 Muchen、Tokyo、Manchester)将不会在您的模型中设置为 属性。对于这种情况,您可以在 CountryChanged 方法中执行类似的操作:
switch (e.Value.ToString())
{
case "01":
CountryCities.Add("001", "Munchen");
MyLocation.CityCode= "001";
...
编辑 2:回复您的评论“谢谢,但我正在寻找输入文本中的绑定值之类的方法。”
<EditForm Model="MyLocation">
<InputSelect TValue="string" @bind-Value="MyLocation.CountryCode">
@if (string.IsNullOrEmpty(MyLocation.CountryCode) == true)
{
<option value="0" selected>[Choose One...]</option>
}
@foreach (var item in Countries)
{
<option value="@item.Key">@item.Value</option>
}
</InputSelect>
@page "/"
<select class="form-control" value="@MyLocation.CountryCode"
@onchange="@((args) => { MyLocation.CountryCode = args.Value.ToString(); SelectCities(args); })">
<option value="">Select Country...</option>
@foreach (var country in countryList)
{
<option value="@country.Code"> @country.Name </option>
}
</select>
<br />
@if (cityList != null && cityList.Any())
{
<select class="form-control" @bind="@MyLocation.CityCode">
<option value="">Select city...</option>
@foreach (var city in cityList)
{
<option value="@city.Code">@city.Name</option>
}
</select>
}
<br />
<button class="btn btn-success" @onclick="() => HandleSave()">Save</button>
@code {
private Location MyLocation = new Location();
private IList<Country> countryList = new List<Country>
{
new Country
{
Code = "001", Name="USA",
Cities = new List<City> { new City { Code = "1", Name = "City1" },
new City { Code = "2", Name = "City2" } }
},
new Country
{
Code = "002", Name="Germany",
Cities = new List<City> { new City { Code = "3", Name = "City1" },
new City { Code = "4", Name = "City2" } }
},
new Country
{
Code = "003", Name="France",
Cities = new List<City> { new City { Code = "5", Name = "City1" },
new City { Code = "6", Name = "City2" } }
},
new Country
{
Code = "004", Name="UK",
Cities = new List<City> { new City { Code = "7", Name = "City1" },
new City { Code = "8", Name = "City2" },
new City { Code = "9", Name = "City3" },
new City { Code = "10", Name = "City4" }}
},
new Country { Code = "005", Name="Russia",
Cities = new List<City> { new City { Code = "11", Name = "City1" } }}
};
private IQueryable<City> cityList;
private void HandleSave()
{
Console.WriteLine($"MyLocation.CountryCode: {MyLocation.CountryCode}");
Console.WriteLine($"MyLocation.CityCode: {MyLocation.CityCode}");
}
private void SelectCities(ChangeEventArgs args)
{
// Note: Each time SelectCities is called MyLocation.CityCode should be set to null.
MyLocation.CityCode = null;
string countryCode = args.Value.ToString();
cityList = (from country in countryList
where country.Code == countryCode
from city in country.Cities
select city).AsQueryable();
}
public class Location
{
public string CountryCode { get; set; }
public string CityCode { get; set; }
}
public class Country
{
public string Code { get; set; }
public string Name { get; set; }
public IList<City> Cities { get; set; }
}
public class City
{
public string Code { get; set; }
public string Name { get; set; }
}
}
现在尝试转换此代码以使用嵌入在 EditForm 中的表单的 InputSelect 组件
我有 2 个级联下拉菜单:
问题是当我点击 Save
按钮时我的模型会是空的。我无法在下拉菜单中使用 bind-value
,因为我无法使用 onchange
事件。只要绑定属性,我怎么能有级联特性呢
代码:
@using Model
<select value="@MyLocation.CountryCode" @onchange="@CountryChanged">
@if (string.IsNullOrEmpty(MyLocation.CountryCode) == true)
{
<option value="0" selected>[Choose One...]</option>
}
@foreach (var item in Countries)
{
<option value="@item.Key">@item.Value</option>
}
</select>
<br />
<select value="@MyLocation.CityCode">
@foreach (var item in CountryCities)
{
<option value="@item.Key">@item.Value</option>
}
</select>
<br />
<button class="btn btn-success" @onclick="() => HandleSave()">Save</button>
@code {
public Location MyLocation { get; set; } = new Location();
private Dictionary<string, string> Countries { set; get; } = new Dictionary<string, string>();
private Dictionary<string, string> CountryCities { set; get; } = new Dictionary<string, string>();
protected override Task OnInitializedAsync()
{
Countries.Add("01", "Germany");
Countries.Add("02", "Japan");
Countries.Add("03", "England");
return base.OnInitializedAsync();
}
private async Task CountryChanged(ChangeEventArgs e)
{
CountryCities.Clear();
switch (e.Value.ToString())
{
case "01":
CountryCities.Add("001", "Munchen");
break;
case "02":
CountryCities.Add("002", "Tokyo");
break;
case "03":
CountryCities.Add("003", "Manchester");
break;
}
}
private void HandleSave()
{
var Country = MyLocation.CountryCode; <--- CountryCode is null
}
}
您可以在 CountryChanged 方法中添加:
MyLocation.CountryCode = e.Value.ToString();
您可以对城市代码执行相同的操作:
<select value="@MyLocation.CityCode" @onchange="@OnCityChanged">
@foreach (var item in CountryCities)
{
<option value="@item.Key">@item.Value</option>
}
@code {
private void OnCityChanged(ChangeEventArgs e) => MyLocation.CityCode = e.Value.ToString();
}
编辑:请注意,要使 OnCityChanged 起作用,用户实际上必须 select 一个值。如果他们不这样做,第一个值(在您的情况下为 Muchen、Tokyo、Manchester)将不会在您的模型中设置为 属性。对于这种情况,您可以在 CountryChanged 方法中执行类似的操作:
switch (e.Value.ToString())
{
case "01":
CountryCities.Add("001", "Munchen");
MyLocation.CityCode= "001";
...
编辑 2:回复您的评论“谢谢,但我正在寻找输入文本中的绑定值之类的方法。”
<EditForm Model="MyLocation">
<InputSelect TValue="string" @bind-Value="MyLocation.CountryCode">
@if (string.IsNullOrEmpty(MyLocation.CountryCode) == true)
{
<option value="0" selected>[Choose One...]</option>
}
@foreach (var item in Countries)
{
<option value="@item.Key">@item.Value</option>
}
</InputSelect>
@page "/"
<select class="form-control" value="@MyLocation.CountryCode"
@onchange="@((args) => { MyLocation.CountryCode = args.Value.ToString(); SelectCities(args); })">
<option value="">Select Country...</option>
@foreach (var country in countryList)
{
<option value="@country.Code"> @country.Name </option>
}
</select>
<br />
@if (cityList != null && cityList.Any())
{
<select class="form-control" @bind="@MyLocation.CityCode">
<option value="">Select city...</option>
@foreach (var city in cityList)
{
<option value="@city.Code">@city.Name</option>
}
</select>
}
<br />
<button class="btn btn-success" @onclick="() => HandleSave()">Save</button>
@code {
private Location MyLocation = new Location();
private IList<Country> countryList = new List<Country>
{
new Country
{
Code = "001", Name="USA",
Cities = new List<City> { new City { Code = "1", Name = "City1" },
new City { Code = "2", Name = "City2" } }
},
new Country
{
Code = "002", Name="Germany",
Cities = new List<City> { new City { Code = "3", Name = "City1" },
new City { Code = "4", Name = "City2" } }
},
new Country
{
Code = "003", Name="France",
Cities = new List<City> { new City { Code = "5", Name = "City1" },
new City { Code = "6", Name = "City2" } }
},
new Country
{
Code = "004", Name="UK",
Cities = new List<City> { new City { Code = "7", Name = "City1" },
new City { Code = "8", Name = "City2" },
new City { Code = "9", Name = "City3" },
new City { Code = "10", Name = "City4" }}
},
new Country { Code = "005", Name="Russia",
Cities = new List<City> { new City { Code = "11", Name = "City1" } }}
};
private IQueryable<City> cityList;
private void HandleSave()
{
Console.WriteLine($"MyLocation.CountryCode: {MyLocation.CountryCode}");
Console.WriteLine($"MyLocation.CityCode: {MyLocation.CityCode}");
}
private void SelectCities(ChangeEventArgs args)
{
// Note: Each time SelectCities is called MyLocation.CityCode should be set to null.
MyLocation.CityCode = null;
string countryCode = args.Value.ToString();
cityList = (from country in countryList
where country.Code == countryCode
from city in country.Cities
select city).AsQueryable();
}
public class Location
{
public string CountryCode { get; set; }
public string CityCode { get; set; }
}
public class Country
{
public string Code { get; set; }
public string Name { get; set; }
public IList<City> Cities { get; set; }
}
public class City
{
public string Code { get; set; }
public string Name { get; set; }
}
}
现在尝试转换此代码以使用嵌入在 EditForm 中的表单的 InputSelect 组件