Невозможно установить сгенерированный jQuery выпадающий список выбранного значения, переданного через модель в ASP .NET MVC - PullRequest
1 голос
/ 20 апреля 2019

У меня есть следующие три раскрывающихся списка в моем MVC View.

@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 в соответствии с доступом пользователя loggedin.Отдел обновляется в соответствии с выбором, сделанным в местах.

Ниже приведен код для того же.


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--");

До этого момента все работало нормально, теперь у меня проблема в двух ситуациях: когда пользователь пытается редактировать и когда пользователь заканчивает добавлять запись.В обеих ситуациях я хочу предварительно установить значения местоположения, отдела и областей.В случае редактирования все значения поступают из модели, в случае сохранения, я хочу сохранить состояние выпадающих списков до ранее выбранных, чтобы пользователю не нужно было снова и снова выбирать эти значения.Ниже приведен мой код в контроллере.

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);
        }

Теперь, раскрывающееся значение местоположения выбирается без каких-либо проблем, поскольку оно исходит от модели, я должен автоматически выбирать местоположение и заполнять отделы, если у пользователя есть доступтолько в одном месте.Ниже приведен код для того же.

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

У меня есть следующий код jquery для предварительного выбора элементов в областях и департаменте, на мой взгляд, этот код не работает, ошибок нет.По умолчанию первый элемент выбирается.

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

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

Не уверен, почему значения отделов и областей не выбираются, проверил значения в модели, войдя в консоль, значения передаются отлично, но Jquery - нетвыбор значений выпадающего списка по некоторым причинам.

1 Ответ

0 голосов
/ 22 апреля 2019

Обнаружил проблему и решение. Проблема в том, что вызовы ajax являются асинхронными, из-за чего мой код пытается установить значения раскрывающихся списков до того, как они будут заполнены. Получил подсказки из следующих ответов

Установка выбранного значения выбора с использованием JQuery из свойства модели MVC

Подождите, пока все запросы JQuery Ajax будут выполнены?

функция javascript ожидает завершения другой функции

Изменил мой код следующим образом, чтобы решить проблему, пожалуйста, имейте меня в виду, что код выглядит некрасиво, решил реорганизовать его позже, чтобы уложиться в сроки.

            $.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');
                }

        }
    });
}
...