无法设置 jQuery 生成的下拉列表选定值通过 ASP .NET MVC 中的模型传递

Unable to set jQuery generated dropdownlist selected value passed through model in ASP .NET MVC

我的 MVC 视图中有以下三个下拉菜单。

@Html.DropDownListFor(m => m.Zone.LocationId,
                        new SelectList(Model.Locations, "Id", "Description"),
                        "--Select Location--",
                        new { @class = "form-control", id = "ddlLocations",
                        onchange = "Change(this)" })

@Html.DropDownListFor(m => m.Zone.DepartmentId,
                        new SelectList(new List<string>()),
                        new { @class = "form-control", id = "ddlDepartments" })

@Html.DropDownListFor(m => m.Zone.AreaId,
                        new SelectList(new List<string>()),
                        new { @class = "form-control", id = "ddlAreas" })

根据登录用户的访问权限,位置来自我的 ViewModel。部门根据 select 位置更新。

以下是相同的代码。


function Change(control) {
            let item = $(control).val();
            if (item !== undefined && item !== "")
             bindDdl("/api/get/DepartmentsByLocation?locationId=" + $(control).val(),
                    $("#ddlDepartments"),
                    "--Select Department--");
            else
                $("#ddlDepartments").empty();
        }


function bindDdl(url, control, displayText, hiddenControl) {
    $(control).empty();
    $.ajax({
        type: "get",
        url: url,
        dataType: "",
        success: function (data) {
            let ddl = $(control);
            ddl.append('<option value=>' 
            + displayText + '</option >');
            for (var i = 0; i < data.length; i++) {
                ddl.append('<option value=' + data[i].id + '>' + data[i].description + '</option >');
            }
            if ($(hiddenControl).val() != "0")
                ddl.val($(hiddenControl).val());
        }
    });
}

我的区域下拉列表从 jquery 使用以下代码填充。

 bindDdl("/api/get/Areas", $("#ddlAreas"), "--Select Area--");

到目前为止一切正常,现在我在两种情况下遇到问题,当用户尝试编辑时以及当用户完成添加记录时。在这两种情况下,我都想预先设置位置、部门和区域的值。在编辑的情况下,所有值都来自模型,在保存的情况下,我想将下拉列表的状态保留为以前 selected 的状态,这样用户就不需要一次又一次地 select 这些值.以下是我在控制器中的代码。

public ActionResult Index(int id = 0)
        {
            ZoneViewModel data = new ZoneViewModel();
            if (id > 0)
                data.Zone = _unitOfWork.Zones.GetDtoById(id);
            if (data.Zone == null)
                data.Zone = new ZoneDto();

            data.Locations =
        (List<LocationDto>)_unitOfWork.Locations.GetLocationsByUserId(UserId);
            if (data.Locations.Count == 1)
                data.Zone.LocationId = data.Locations[0].Id;

            if (id <= 0 && Session["LocationId"] != null)
            {
                data.Zone.LocationId = (int)Session["LocationId"];
                data.Zone.DepartmentId = (int)Session["DepartmentId"];
                data.Zone.AreaId = (int)Session["AreaId"];
            }

            return View("Zone", data);
        }

现在,位置下拉值得到 selected 没有任何问题,因为它来自模型,如果用户只能访问,我必须自动 select 位置并填充部门一个地点。以下是相同的代码。

 if ($("#ddlLocations > option").length === 2)
                Change($("#ddlLocations"));

我有以下 jquery 代码来预 select 我认为区域和部门中的项目,这个特定代码不起作用,没有错误。默认情况下,第一项正在 selected.

    if (@Model.Zone.DepartmentId > 0) 
        $("#ddlDepartments").val("@Model.Zone.DepartmentId.ToString()");

    if (@Model.Zone.AreaId > 0)
        $("#ddlAreas").val('@Model.Zone.AreaId.ToString()');

不确定为什么部门和区域值没有得到 selected,通过登录控制台检查模型中的值,值得到完美传递,但 Jquery 不是 select出于某种原因调整下拉列表值。

找到问题和解决方案。问题是 ajax 调用是异步的,因此我的代码试图在填充下拉列表值之前设置它们。从以下答案中得到线索

Setting selected value of a Select using JQuery from an MVC model property

Wait until all jQuery Ajax requests are done?

javascript function wait until another function to finish

修改我的代码如下以解决这个问题,请多多包涵,因为代码看起来很丑,决定稍后重构它,以满足最后期限。

            $.when(
                bindDdl("/api/get/LocationsByUserId?UserId=@User.Identity.GetUserId()",
                    $("#ddlLocations"),
                    "--Select Location--",
                    undefined,
                    false),
                bindDdl("/api/get/Areas", $("#ddlAreas"), "--Select Area--")).done(function(a1) {

                if (@Model.Zone.AreaId > 0)
                    $("#ddlAreas").val('@Model.Zone.AreaId.ToString()');


                if (@Model.Zone.LocationId > 0)
                    $("#ddlLocations").val('@Model.Zone.LocationId');


                if (@Model.Zone.DepartmentId > 0) {
                    $.when(bindDdl("/api/get/DepartmentsByLocation?locationId=" + $("#ddlLocations").val(),
                        $("#ddlDepartments"),
                        "--Select Department--")).done(function() {
                        $("#ddlDepartments").val('@Model.Zone.DepartmentId.ToString()');
                    });
                }
                else
                {
                    let ctrl = $("#ddlLocations");
                    if ($(ctrl)[0].length === 2) {
                        $(ctrl)[0].selectedIndex = "1";
                        $(ctrl).trigger('change');
                    }
                }
            });
        });

        function Change(control) {
            let item = $(control).val();
            if (item !== undefined && item !== "")
                bindDdl("/api/get/DepartmentsByLocation?locationId=" + $(control).val(),
                    $("#ddlDepartments"),
                    "--Select Department--");
            else
                $("#ddlDepartments").empty();
        }

而bindDdl函数如下

function bindDdl(url, control, displayText, hiddenControl, raiseEvent) {
    console.log(displayText);
    console.log(typeof raiseEvent);
    raiseEvent = (typeof raiseEvent === 'undefined') ? true : raiseEvent;
    console.log(raiseEvent);
    $(control).empty();
  return $.ajax({
        type: "get",
        url: url,
        dataType: "",
        success: function (data) {
            let ddl = $(control);
            ddl.append('<option value=>' + displayText + '</option >');
            for (var i = 0; i < data.length; i++) {
                ddl.append('<option value=' + data[i].id + '>' + data[i].description + '</option >');
            }
            if ($(hiddenControl).val() != "0")
                ddl.val($(hiddenControl).val());

            if ($(control)[0].length === 2 && raiseEvent) {
                    $(control)[0].selectedIndex = "1";
                    $(control).trigger('change');
                }

        }
    });
}