下拉列表 onchanged - 无法持久化 ViewModel

Dropdownlist onchanged - Trouble persisting ViewModel

我是一名 ASP.NET 开发人员,正在努力掌握 MVC。

我正在创建一个注册页面,我有 3 个下拉菜单。

现在必须首先加载第一个下拉列表才能加载国家/地区。在此基础上加载省份,然后在此基础上加载该省的城市。

我遇到的问题是,在第一次更改时它保留了我选择的值,但在第二次更改时似乎一切都丢失了。

我这么长时间才加载国家就加载了注册视图。然后 javascript 将其发布到操作中。

cshtml

<label class="col-md-3 col-xs-5 control-label">Country:</label>
<div class="col-md-9 col-xs-7">
    @Html.DropDownListFor(x => x.CountryId, (IEnumerable<SelectListItem>)ViewBag.CountryItems, "Please Select", new { @class = "form-control select", @onchange = "CallChangefunc(this.value, null)" })
</div>
</div>
<div class="form-group">
<label class="col-md-3 col-xs-5 control-label">Province:</label>
<div class="col-md-9 col-xs-7">
        @Html.DropDownListFor(x => x.ProvinceId, (IEnumerable<SelectListItem>)ViewBag.ProvinceItems, "Please Select", new { @class = "form-control select", @onchange = "CallChangefunc(null, this.value)" })
</div>
</div>
<div class="form-group">
<label class="col-md-3 col-xs-5 control-label">City:</label>
<div class="col-md-9 col-xs-7">
    @Html.DropDownListFor(x => x.CityId, (IEnumerable<SelectListItem>)ViewBag.CityItems, "Please Select", new { @class = "form-control select" })
</div>
</div>

javascript

function CallChangefunc(countryId, provinceId) {
    window.location.href = "/Master/SetDropDowns?provinceId=" + provinceId + "&countryId=" + countryId ;
}

第一个 "Register" 加载第一个然后 SetDropDowns 被调用 onchanged。

我加载了 viewbags(SelectedItemLists),否则我会在刷新时出错。有没有更好的方法来编码 viewbags 不在两个地方?

[HttpGet]
    public ActionResult Register()
    {
        IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
            {
                Value = ci.Id.ToString(),
                Text = ci.Name
            });

        ViewBag.CountryItems = CountryItems;

        IEnumerable<SelectListItem> ProvinceItems = BusinessAPI.ProvinceManager.GetAllProvincesByCountryId(0).Select(ci => new SelectListItem
        {
            Value = ci.Id.ToString(),
            Text = ci.Name
        });

        ViewBag.ProvinceItems = ProvinceItems;

        IEnumerable<SelectListItem> CityItems = BusinessAPI.CityManager.GetAllCitiesByProvinceId(0).Select(ci => new SelectListItem
        {
            Value = ci.Id.ToString(),
            Text = ci.Name
        });

        ViewBag.CityItems = CityItems;

        return View();
    }

    public ActionResult SetDropDowns(string provinceId, string countryId)
    {
        IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
        {
            Value = ci.Id.ToString(),
            Text = ci.Name
        });

        ViewBag.CountryItems = CountryItems;

        int countId = 0;
        if (countryId == "null")
            countryId = string.Empty;

        if (TempData["CountryId"] == null)
        {
            if (!string.IsNullOrEmpty(countryId))
            {
                countId = Convert.ToInt32(countryId);
                TempData["CountryId"] = countId;
            }
        }
        else
            countId = Convert.ToInt32(TempData["ProvinceId"]);

        IEnumerable<SelectListItem> ProvinceItems = BusinessAPI.ProvinceManager.GetAllProvincesByCountryId(Convert.ToInt32(countId)).Select(ci => new SelectListItem
        {
            Value = ci.Id.ToString(),
            Text = ci.Name
        });

        ViewBag.ProvinceItems = ProvinceItems;

        int provId = 0;
        if (provinceId == "null")
            provinceId = string.Empty;

        if (TempData["ProvinceId"] == null)
        {
            if (!string.IsNullOrEmpty(provinceId))
            {
                provId = Convert.ToInt32(provinceId);
                TempData["ProvinceId"] = provId;
            }
        }
        else
            provId = Convert.ToInt32(TempData["ProvinceId"]);

        IEnumerable<SelectListItem> CityItems = BusinessAPI.CityManager.GetAllCitiesByProvinceId(provId).Select(ci => new SelectListItem
        {
            Value = ci.Id.ToString(),
            Text = ci.Name
        });

        ViewBag.CityItems = CityItems;

        return View("Register");
    }

问题是您没有告诉他们被选中,像下面的示例一样修改具有 SelectListItem 的列表,以告诉列表中的项目是 Selected.

IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
{
    Value = ci.Id.ToString(),
    Text = ci.Name,
    Selected = ci.id.ToString() == countryId // if match the condition is selected
});

此外,要同时选中两个列表,您可以修改视图。 修改 javascript 函数以始终发送 countryId。这样做会始终选择当前国家/地区,即使您更改省份也是如此。

function CallChangefunc(provinceId) {
    var countries = document.getElementById("CountryId");
    var countryId = countries.options[countries.selectedIndex].value; 
    window.location.href = "/Master/SetDropDowns?provinceId=" + provinceId + "&countryId=" + countryId ;
}

请注意,在第一个下拉列表 CallChangefunc(null) 中,我们告诉我们没有选择省份,这是真的。

<div class="col-md-9 col-xs-7">
    @Html.DropDownListFor(x => x.CountryId, (IEnumerable<SelectListItem>)ViewBag.CountryItems, "Please Select", new { @class = "form-control select", @onchange = "CallChangefunc(null)" })
</div>

在第二个下拉列表中,我们发送 CallChangefunc(this.value),以此告知选择了哪个省份来获取城市,并在回发后保持当前选择的值。因为 countryId 总是发送,所以它会保持不变。

<div class="col-md-9 col-xs-7">
    @Html.DropDownListFor(x => x.ProvinceId, (IEnumerable<SelectListItem>)ViewBag.ProvinceItems, "Please Select", new { @class = "form-control select", @onchange = "CallChangefunc(this.value)" })
</div>