模型属性未绑定到 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 组件