лучший способ загрузить 2 выпадающего меню в mvc

Вот как я загружаюсь в состояние загрузки страницы и раскрывающееся меню города:

Мой метод controllerа :

Это первый метод, вызывающий загрузку страницы.

public ActionResult Index() { var states = GetStates(); var cities = Enumerable.Empty(); ViewBag.States = states; ViewBag.Cities = cities; } private IEnumerable 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 States = ViewBag.States; IEnumerable 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 = 'Select City'; $(responce).each(function () { html += ''+this.Text+'' }); $("#ddlCity").html(html); } }); } 

Какой-нибудь лучший способ, чтобы это загрузить статус и город?

 public class HomeController : Controller { public ActionResult Index(int id=0) { Person model = null; var states = GetStates().ToList(); var cities = Enumerable.Empty(); 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(); 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(); return View("Index"); } } private IEnumerable GetStates() { using (var db = new DataEntities()) { return db.States.ToList().Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() }); } } private IEnumerable 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(); 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 
@if (Model.Count() == 0) { } else { foreach (var item in Model) { } }
First Name Last Name Email City State Edit

No data available

@item.FirstName @item.LastName @item.Email @item.CityName @item.StateName @if (ViewBag.Title == "Home Ajax" || Request.IsAjaxRequest()) { Update @Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {OnSuccess="deleteSuccess",OnBegin="showLoader",OnComplete="hideLoader" }) } else { @Html.ActionLink("Update", "Index", new { id = item.Id }) @Html.ActionLink("Delete", "Delete", new { id = item.Id }) }
@model Person @{ ViewBag.Title = "Home Ajax"; IEnumerable persons = ViewBag.Persons; IEnumerable States = ViewBag.States; IEnumerable Cities = ViewBag.Cities; IEnumerable fullStates=ViewBag.CityStates; } @section featured { } @section styles{ td,th { border:1px solid; padding:5px 10px; } select { padding:5px 2px; width:310px; font-size:16px; } } @section scripts{ @Scripts.Render("~/bundles/jqueryval") 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 = 'Select City'; $(obj).each(function () { html += '' + this.Name + '' }); $("#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(); } }

Add Personal Detail

@using (Ajax.BeginForm("SavePersonDetail", "Home", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "personList" ,OnSuccess="insertSuccess",OnBegin="showLoader",OnComplete="hideLoader"})) { @Html.HiddenFor(m => m.Id);
  1. @Html.LabelFor(m => m.FirstName) @Html.TextBoxFor(m => m.FirstName, new { id = "txtfirstName" }) @Html.ValidationMessageFor(m => m.FirstName)
  2. @Html.LabelFor(m => m.LastName) @Html.TextBoxFor(m => m.LastName, new { id = "txtlastName" }) @Html.ValidationMessageFor(m => m.LastName)
  3. @Html.LabelFor(m => m.Email) @Html.TextBoxFor(m => m.Email, new { id = "txtemail" }) @Html.ValidationMessageFor(m => m.Email)
  4. @Html.Label("State") @Html.DropDownList("State", States, "Select State", new { onchange = "loadCities(this)", id = "ddlState" })
  5. @Html.LabelFor(m => m.CityId) @Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id = "ddlCity" }) @Html.ValidationMessageFor(m => m.CityId)
}

Person List

@Html.Partial("_personDetail", persons)

5 Solutions collect form web for “лучший способ загрузить 2 выпадающего меню в mvc”

Вы пытаетесь использовать ajax в порядке, хотя я бы рекомендовал несколько лучших практик, включая использование модели представления со свойствами для StateID , CityID StateList и CityList и использование ненавязчивого JavaScript вместо того, чтобы загрязнять вас разметкой поведением и генерировать первый («выберите», ) с 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? 

SCRIPT

 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($('').val('').text('Please select')); $.each(response, function(index, item) { cities.append($('').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.

В controllerе

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

Это правильный подход, но вы можете упростить свой javascript:

 function loadCities(obj) { $.getJSON("/Home/GetCities", function (data) { var html = ''; $(data).each(function () { html += '' }); $("#ddlCity").html(html); }); } 

Дальнейшее упрощение: добавьте элемент по умолчанию (выберите город) на стороне сервера, поэтому ваш javascript будет меньше.

Вот как я сделал бы это без обновления страницы, считая, что список городов не слишком длинный. Я предполагаю, что вы можете создать метод GetStatesAndCities для возврата Словаря.

 public ActionResult Index() { Dictionary> statesAndCities = GetStatesAndCities(); ViewBag.StatesAndCities = Json(statesAndCities); } 

Тогда в представлении:

 var states = JSON.parse(@ViewBag.StatesAndCities); function loadCities(obj) { var cities = states[$(obj).val()]; var html = ''; $(cities).each(function () { html += '' }); $("#ddlCity").html(html); } 

Таким образом, когда государство изменило поле городов с обновлением сразу же, без необходимости обратного вызова.

отказ от ответственности: это не кодовый ответ, есть много других ответов.

Я думаю, что лучший способ сохранить себя счастливым, чтобы разделить страницы пользовательского интерфейса с данными => превратить их в вызовы API:

  • / GetCities
  • / GetStates

Теперь вы можете просто оставить пустой выбор на Razor, отображая страницу. И используйте плагин Jquery / Bootstrap для создания windows выбора AJAX.

Таким образом, когда пользователь перестает печатать свой поиск, эта строка поиска может быть отправлена ​​с вызовом AJAX (например: /GetStates?search=test ), а затем небольшой результат может быть отправлен обратно на веб-сайт.

Это дает:

  • Лучшее разделение по коду
  • Лучший пользовательский опыт.
  • Меньшие загрузки страниц (так как вы больше не отправляете все параметры пользователю, когда он запрашивает страницу, только когда он открывает окно выбора).

Как насчет использования нокаута?

Нокаут – это библиотека JavaScript, которая помогает создавать богатые, отзывчивые пользовательские интерфейсы для отображения и редактирования с чистой базовой моделью данных

Вы должны использовать ajax для своих городов. Но с нокаутом вам не нужно писать

var html = ''; $(responce).each(function () { html += ''}); $("#ddlCity").html(html);

в вашем javascript.Knockout делает его простым.

Вы можете просто написать:

  function CityModel() { var self = this; // that means this CityModel self.cities = ko.observableArray([]); self.getCities = function () { $.ajax({ url: "/Home/GetCities", data: { id: $(obj).val() }, contentType: "application/json", success: self.cities }); } } ko.applyBindings(new CityModel()); 

это все. Но вы должны привязать свои данные к элементам html. Вместо использования: @Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity"})

Вы можете использовать:

   

или вы можете смешивать бритву и нокаут:

 @Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity",data_bind:"options:cities,optionsValue:\"Id\",optionsText:\"CityName\""}) 

Еще одна вещь, которую вы должны назвать GetCities при изменении State , вы можете:

 @Html.DropDownList("State", States, "Select State", new {data_bind:"event:\"change\":\"$root.GetCities\""}) 

Не пугайтесь с \ “\” вещами, потому что " является escape-символом, и мы должны сказать, что razor, которую я хочу использовать”, используя \ перед ним.

Вы можете найти больше информации о нокауте: нокаут

И смешивание с бритвой: Razor и Knockout

Ps: yes, используя нокаут, приостанавливает нас от Razor и Mvc. Вам нужно написать еще один ViewModel. Но, подобно этим ситуациям, ko полезен. Смешивание бритвы и нокаута – еще один вариант для вас.

Interesting Posts

C # reflection – загрузить сборку и вызвать метод, если он существует

Экранное меню Windows 10 Power + WinX и контекстное меню

Outlook 2013 / Windows 8.1: удаление электронной почты из уведомлений toast

Swift – эквивалент IBOutletCollection

Неизвестная escape-последовательность для строки пути, содержащей обратную косую черту

Как отправлять SMS-сообщения с моего компьютера через Android-телефон?

Глобальные ярлыки KDE перестали работать. Проблемы с KDED?

Есть ли способ использовать английский как системный язык в Windows 8.1, но удалить его с языковой панели?

Как я могу избежать окна сообщения буфера обмена при копировании больших объемов данных в Excel?

Панель задач Windows 7, создайте всплывающие меню?

Как вы можете проверить, сколько питания USB-порт может доставить?

Не найдено подходящих драйверов для ‘jdbc: mysql: // localhost: 3306 / mysql

Хранение объектов ggplot в списке из цикла в R

Вызов собственного метода дважды из сторонней библиотеки в Activity приводит к закрытию приложения Android

Как использовать Терминал для рекурсивного удаления всех .svn-папок?

Давайте будем гением компьютера.