这是我如何加载页面加载状态和城市下拉列表的方式:
我的控制器方法 :
这是加载页面时调用的第一个方法。
public ActionResult Index() { var states = GetStates(); var cities = Enumerable.Empty<SelectListItem>(); ViewBag.States = states; ViewBag.Cities = cities; } private IEnumerable<SelectListItem> GetStates() { using (var db = new DataEntities()) { return db.States.Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() }); } } [HttpGet] public ActionResult GetCities(int id) { using (var db = new DataEntities()) { var data = db.Cities.Where(d=>d.StateId==id).Select(d => new { Text = d.CityName, Value = d.Id }).ToList(); return Json(data, JsonRequestBehavior.AllowGet); } }
我的看法 :
IEnumerable<SelectListItem> States = ViewBag.States; IEnumerable<SelectListItem> Cities = ViewBag.Cities; @Html.DropDownList("State", States, "Select State", new { onchange="loadCities(this)"}) @Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity"}) function loadCities(obj) { $.ajax({ url: "/Home/GetCities", data: { id: $(obj).val() }, contentType:"application/json", success:function(responce){ var html = '<option value="0">Select City</option>'; $(responce).each(function () { html += '<option value="'+this.Value+'">'+this.Text+'</option>' }); $("#ddlCity").html(html); } }); }
还有什么更好的方法来加载州和城市下拉菜单?
public class HomeController : Controller { public ActionResult Index(int id=0) { Person model = null; var states = GetStates().ToList(); var cities = Enumerable.Empty<SelectListItem>(); if (id > 0) { using (var db = new DataEntities()) { model = db.People.Include("City").FirstOrDefault(d => d.Id == id); if (model == null) model = new Person(); else { states.First(d => d.Value == model.City.StateId.ToString()).Selected = true; cities = db.Cities.Where(d => d.StateId == model.City.StateId).ToList().Select(d => new SelectListItem { Text = d.CityName,Value=d.Id.ToString(),Selected=d.Id==model.CityId }); } } } else { model = new Person(); } ViewBag.States = states; ViewBag.Cities = cities; ViewBag.Persons = GetPersons(); return View(model); } [HttpGet] public ActionResult GetCities(int id) { using (var db = new DataEntities()) { var data = db.Cities.Where(d=>d.StateId==id).Select(d => new { Text = d.CityName, Value = d.Id }).ToList(); return Json(data, JsonRequestBehavior.AllowGet); } } public ActionResult SavePersonDetail([Bind(Exclude = "Id")] Person model) { // var employeeDal= new Emploee(); //employee.firstname=model. if (ModelState.IsValid) { var Id = model.Id; int.TryParse(Request["Id"], out Id); using (var db = new DataEntities()) { if (Id > 0) { var person = db.People.FirstOrDefault(d => d.Id == Id); if (person != null) { model.Id = Id; db.People.ApplyCurrentValues(model); } } else { db.People.AddObject(model); } db.SaveChanges(); } } if (!Request.IsAjaxRequest()) { ViewBag.States = GetStates(); ViewBag.Persons = GetPersons(); ViewBag.Cities = Enumerable.Empty<SelectListItem>(); return View("Index"); } else { return PartialView("_personDetail",GetPersons()); } } public ActionResult Delete(int id) { using (var db = new DataEntities()) { var model = db.People.FirstOrDefault(d => d.Id == id); if (model != null) { db.People.DeleteObject(model); db.SaveChanges(); } } if (Request.IsAjaxRequest()) { return Content(id.ToString()); } else { ViewBag.States = GetStates(); ViewBag.Persons = GetPersons(); ViewBag.Cities = Enumerable.Empty<SelectListItem>(); return View("Index"); } } private IEnumerable<SelectListItem> GetStates() { using (var db = new DataEntities()) { return db.States.ToList().Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() }); } } private IEnumerable<Person> GetPersons() { using (var db = new DataEntities()) { return db.People.Include("City").Include("City.State").ToList(); } } public ActionResult HomeAjax() { ViewBag.States = GetStates(); ViewBag.Cities = Enumerable.Empty<SelectListItem>(); using (var db = new DataEntities()) { var data = db.States.Include("Cities").Select(d => new { Id = d.Id, Name = d.StateName, Cities = d.Cities.Select(x => new { Id=x.Id,Name=x.CityName}) }).ToList(); ViewBag.CityStateJson = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(data); } ViewBag.Persons = GetPersons(); return View(); } } @model IEnumerable<Person> <div> <table> <tr> <th> First Name </th> <th> Last Name </th> <th> Email </th> <th> City </th> <th> State </th> <th> Edit </th> </tr> @if (Model.Count() == 0) { <tr> <td colspan="6"> <h3>No data available</h3> </td> </tr> } else { foreach (var item in Model) { <tr data-id="@item.Id"> <td data-id="fn">@item.FirstName</td> <td data-id="ln">@item.LastName</td> <td data-id="email">@item.Email</td> <td data-id="cn">@item.CityName<input type="hidden" value="@item.CityId" /></td> <td>@item.StateName</td> <td> @if (ViewBag.Title == "Home Ajax" || Request.IsAjaxRequest()) { <a href="javascript:void(0);" onclick="Edit(this,@item.Id);">Update</a> <span>@Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {OnSuccess="deleteSuccess",OnBegin="showLoader",OnComplete="hideLoader" })</span> } else { <span>@Html.ActionLink("Update", "Index", new { id = item.Id })</span> <span>@Html.ActionLink("Delete", "Delete", new { id = item.Id })</span> } </td> </tr> } } </table> </div> @model Person @{ ViewBag.Title = "Home Ajax"; IEnumerable<Person> persons = ViewBag.Persons; IEnumerable<SelectListItem> States = ViewBag.States; IEnumerable<SelectListItem> Cities = ViewBag.Cities; IEnumerable<State> fullStates=ViewBag.CityStates; } @section featured { <section class="featured"> <div class="content-wrapper"> <hgroup class="title"> <h1>@ViewBag.Title.</h1> </hgroup> </div> </section> } @section styles{ <style type="text/css"> td,th { border:1px solid; padding:5px 10px; } select { padding:5px 2px; width:310px; font-size:16px; } </style> } @section scripts{ @Scripts.Render("~/bundles/jqueryval") <script type="text/javascript"> var jsonArray = @Html.Raw(ViewBag.CityStateJson) function clearValues() { $("input[type='text'],select").val(''); $("input[type='hidden'][name='Id']").val(0); } function loadCities(obj) { for (var i = 0; i < jsonArray.length; i++) { if (jsonArray[i].Id == parseInt($(obj).val())) { fillCity(jsonArray[i].Cities); break; } } } function Edit(obj, Id) { // alert("hi") $("input[type='hidden'][name='Id']").val(Id); var tr = $(obj).closest("tr"); $("#txtfirstName").val($("td[data-id='fn']", tr).text().trim()); $("#txtlastName").val($("td[data-id='ln']", tr).text().trim()); $("#txtemail").val($("td[data-id='email']", tr).text().trim()); var city = $("td[data-id='cn'] input[type='hidden']", tr).val(); var state; for (var i = 0; i < jsonArray.length; i++) { for (var j = 0; j < jsonArray[i].Cities.length; j++) { if (jsonArray[i].Cities[j].Id == parseInt(city)) { state = jsonArray[i].Id; break; } } if (state) { fillCity(jsonArray[i].Cities); break; } } $("#ddlState").val(state); $("#ddlCity").val(city); } function fillCity(obj) { var html = '<option value="0">Select City</option>'; $(obj).each(function () { html += '<option value="' + this.Id + '">' + this.Name + '</option>' }); $("#ddlCity").html(html); } function deleteSuccess(responce) { alert("record deleted successfully"); $("tr[data-id='" + responce + "']").remove(); } function insertSuccess() { alert("Record saved successfully"); clearValues(); } function showLoader() { $("#overlay").show(); } function hideLoader() { $("#overlay").hide(); } </script> } <h3>Add Personal Detail</h3> @using (Ajax.BeginForm("SavePersonDetail", "Home", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "personList" ,OnSuccess="insertSuccess",OnBegin="showLoader",OnComplete="hideLoader"})) { @Html.HiddenFor(m => m.Id); <ol class="round"> <li> @Html.LabelFor(m => m.FirstName) @Html.TextBoxFor(m => m.FirstName, new { id = "txtfirstName" }) @Html.ValidationMessageFor(m => m.FirstName) </li> <li> @Html.LabelFor(m => m.LastName) @Html.TextBoxFor(m => m.LastName, new { id = "txtlastName" }) @Html.ValidationMessageFor(m => m.LastName) </li> <li> @Html.LabelFor(m => m.Email) @Html.TextBoxFor(m => m.Email, new { id = "txtemail" }) @Html.ValidationMessageFor(m => m.Email) </li> <li> @Html.Label("State") @Html.DropDownList("State", States, "Select State", new { onchange = "loadCities(this)", id = "ddlState" }) </li> <li> @Html.LabelFor(m => m.CityId) @Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id = "ddlCity" }) @Html.ValidationMessageFor(m => m.CityId) </li> </ol> <input type="submit" value="Save" /> <input type="button" value="Cancel" onclick="clearValues();"/> } <h2> Person List </h2> <div style="position:fixed;text-align:center;top:0;bottom:0;left:0;right:0;z-index:10;background-color:black;opacity:0.6;display:none;" id="overlay"> <img style="position:relative;top:370px" src="~/Images/ajax-loader.gif" /> </div> <div id="personList"> @Html.Partial("_personDetail", persons) </div>
尽管我会建议一些更好的做法,包括使用具有StateID,CityID StateList和属性的视图模型CityList,并使用Unobtrusive JavaScript而不是使用行为来污染您的标记,并使用ajax来生成第一个(“请选择”)选项,您可以使用ajax更好null值而不是0它可以与[Required]属性一起使用
StateID
CityID
StateList
CityList
null
0
[Required]
的HTML
@Html.DropDownList(m => m.StateID, States, "Select State") // remove the onchange @Html.DropDownListFor(m => m.CityID, Cities, "Select City") // why change the default ID?
脚本
var url = '@Url.Action("GetCities", "Home")'; // use the helper (dont hard code) var cities = $('#CityID'); // cache the element $('#StateID').change(function() { $.getJSON(url, { id: $(this).val() }, function(response) { // clear and add default (null) option cities.empty().append($('<option></option>').val('').text('Please select')); $.each(response, function(index, item) { cities.append($('<option></option>').val(item.Value).text(item.Text)); }); }); });
如果要渲染多个项目(例如,您要让用户选择他们最近访问的10个城市),则可以缓存第一个呼叫的结果,以避免重复呼叫,因为他们的选择可能包括来自同一州的城市。
var cache = {}; $('#StateID').change(function() { var selectedState = $(this).val(); if (cache[selectedState]) { // render the options from the cache } else { $.getJSON(url, { id: selectedState }, function(response) { // add to cache cache[selectedState] = response; ..... }); } });
最后,根据您对不使用ajax进行操作的评论,您可以将所有城市传递到视图,并将它们分配给javascript数组。如果您有几个国家/地区,每个城市都有几个城市,我只会建议您这样做。这是在略微增加初始加载时间与进行ajax调用时略微延迟之间取得平衡的问题。
在控制器中
model.CityList = db.Cities.Select(d => new { City = d.CountryID, Text = d.CityName, Value = d.Id }).ToList();
在视图中(脚本)
// assign all cities to javascript array var allCities= JSON.parse('@Html.Raw(Json.Encode(Model.CityList))'); $('#StateID').change(function() { var selectedState = $(this).val(); var cities = $.grep(allCities, function(item, index) { return item.CountryID == selectedState; }); // build options based on value of cities });