better way to load 2 dropdown in mvc

后端 未结 5 760
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 03:05

This is how i am loading on page load state and city dropdown:

My Controller method:

This is the first method which is calling when page is

5条回答
  •  暖寄归人
    2020-11-22 03:18

    You approach using ajax is fine although I would recommend a few better practices including using a view model with properties for StateID, CityID StateList and CityList, and using Unobtrusive JavaScript rather than polluting you markup with behavior, and generating the first ("please select") option with a null value rather than 0 so it can be used with the [Required] attribute

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

    If you were rendering multiple items (say you were asking the user to select their last 10 cities they visited), you can cache the result of the first call to avoid repeated calls where their selections may include cities from the same state.

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

    Finally, in response to your comments regarding doing it without ajax, you can pass all the cities to the view and assign them to a javascript array. I would only recommend this if you have a few countries, each with a few cities. Its a matter of balancing the slight extra initial load time vs the slight delay in making the ajax call.

    In the controller

    model.CityList = db.Cities.Select(d => new { City = d.CountryID, Text = d.CityName, Value = d.Id }).ToList();
    

    In the view (script)

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

提交回复
热议问题