我的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" })
根据登录用户的访问,位置来自我的视图模型。部门根据在地点进行的选择进行更新。
以下是相同的代码。
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填充My Areas下拉列表。
bindDdl("/api/get/Areas", $("#ddlAreas"), "--Select Area--");
一切正常,直到这里,现在我在两种情况下有问题,当用户尝试编辑和用户完成添加记录时。在这两种情况下,我想预先设置位置,部门和区域的值。在编辑的情况下,所有值都来自模型,包含Save,我想保留下拉状态到先前选择的状态,这样用户就不必一次又一次地选择这些值。以下是我在控制器中的代码。
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代码在我的视图中预先选择区域和部门中的项目,这个特殊代码不起作用,没有错误。通过defaut,第一个项目被选中。
if (@Model.Zone.DepartmentId > 0)
$("#ddlDepartments").val("@Model.Zone.DepartmentId.ToString()");
if (@Model.Zone.AreaId > 0)
$("#ddlAreas").val('@Model.Zone.AreaId.ToString()');
不确定为什么没有选择部门和区域值,通过登录控制台检查模型中的值,值完全传递,但Jquery没有因某种原因选择下拉列表值。
找出问题和解决方案。问题是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/[email protected]()",
$("#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');
}
}
});
}