这里有一个不错的方法:
假设我们有两个下拉列表,国家和城市,城市下拉列表默认为禁用状态,当选择一个国家时会发生以下情况:
1. city drop down list gets enabled.
2. An AJAX call is made to an action method with the selected country and a list of cities is returned.
3. the city drop down list is populated with the JSON data sent back.
原始代码的荣誉归于
King Wilder,来源于
MVC Central。这个例子是从他在
Golf Tracker Series中的代码中提取出来的简化版本。
HTML
<select id="Country">
// a List of Countries Options Goes Here.
</select></div>
<select id="City" name="City" disabled="disabled">
// To be populated by an ajax call
</select>
JavaScript
$("#Country").change(function() {
var countryVal = $(this).val();
var citySet = $("#City");
if (countryVal.length > 0) {
citySet.attr("disabled", false);
adjustCityDropDown();
} else {
citySet.attr("disabled", true);
citySet.emptySelect();
}
});
function adjustCityDropDown() {
var countryVal = $("#Country").val();
var citySet = $("#City");
if (countryVal.length > 0) {
$.getJSON("/City/GetCities/" + countryVal ,
function(data) {
citySet.loadSelect(data);
});
}
}
动作方法
[HttpGet]
public ActionResult GetCities(string country)
{
Check.Require(!string.IsNullOrEmpty(country), "State is missing");
var query = // get the cities for the selected country.
// Convert the results to a list of JsonSelectObjects to
// be used easily later in the loadSelect Javascript method.
List<JsonSelectObject> citiesList = new List<JsonSelectObject>();
foreach (var item in query)
{
citiesList.Add(new JsonSelectObject { value = item.ID.ToString(),
caption = item.CityName });
}
return Json(citiesList, JsonRequestBehavior.AllowGet);
}
重要提示:
1. JsonSelectObject
在将结果转换为选项标签并在下面的javascript loadSelect
方法中使用时,有助于使事情变得更加容易。它基本上是一个具有两个属性值和标题的类:
public class JsonSelectObject
{
public string value { get; set; }
public string caption { get; set; }
}
2. loadSelect
函数是一个辅助方法,它接受一个最初类型为JsonSelectObject
的json对象列表,并将其转换为要注入到调用下拉列表中的选项列表。这是来自“jQuery In Action”书籍中的一个很酷的技巧,正如原始代码中引用的那样,它包含在一个名为jquery.jqia.selects.js
的文件中,您需要引用它。以下是该js文件中的代码:
(function($) {
$.fn.emptySelect = function() {
return this.each(function() {
if (this.tagName == 'SELECT') this.options.length = 0;
});
}
$.fn.loadSelect = function(optionsDataArray) {
return this.emptySelect().each(function() {
if (this.tagName == 'SELECT') {
var selectElement = this;
selectElement.add(new Option("[Select]", ""), null);
$.each(optionsDataArray, function(index, optionData) {
var option = new Option(optionData.caption,
optionData.value);
if ($.browser.msie) {
selectElement.add(option);
}
else {
selectElement.add(option, null);
}
});
}
});
}
})(jQuery);
这种方法可能比较复杂,但最终你会得到一个干净简洁的代码,在其他地方也可以使用。
希望这对你有所帮助。
更新
在AJAX调用中使用POST而不是GET
您可以用以下代码替换$.getJSON
方法,以便使用POST方式进行Ajax调用。
$.post("/City/GetCities/", { country: countryVal }, function(data) {
citySet.loadSelect(data);
});
请记得将您的Action方法更改为接受POST请求,通过将[HttpGet]注释更改为[HttpPost],并在Action方法中返回结果时删除
JsonRequestBehavior.AllowGet
。
重要提示:
请注意,我们使用所选项目的值而不是名称。例如,如果用户选择了以下选项。
<option value="US">United States</option>
然后,“US”将被发送到Action方法,而不是“United States”。
更新2:在控制器中访问所选值
假设您的Vehicle视图模型中有以下两个属性:
public string Maker { get; set; }
public string Model { get; set; }
同时,您需要使用与ViewModel属性相同的名称来命名选择元素。
<select id="Maker" name="Maker">
// a List of Countries Options Goes Here.
</select></div>
<select id="Model" name="Model" disabled="disabled">
// To be populated by an ajax call
</select>
然后选择的值将自动绑定到您的ViewModel中,您可以直接在Action方法中访问它们。
如果页面与该ViewModel强类型化,则此操作将起作用。
注意:对于第一个列表(制造商列表),您可以在ViewModel中创建一个类型为SelectList的MakersList,并使用HTML助手自动填充您的Makers下拉列表,其中包含ViewModel中的列表。代码将类似于以下内容:
<%= Html.DropDownListFor(model => model.Maker, Model.MakersList) %>
在这种情况下,此选择器生成的名称也将是“Maker”(ViewModel中属性的名称)。
我希望这就是您要寻找的答案。