0

我有级联下拉列表以在第二个下拉列表中显示有关第一个下拉列表中所选项目的项目,为此我已经这样做了......控制器的代码

namespace MvcSampleApplication.Controllers
{
    public class CascadeListController : Controller
    {
        public ActionResult Index()
        {
            List<SelectListItem> state = new List<SelectListItem>();
            state.Add(new SelectListItem { Text = "State1", Value = "State1" });
            state.Add(new SelectListItem { Text = "State2", Value = "State2" });
            ViewBag.StateName = new SelectList(state, "Value", "Text");
            return View("BasicDrop");
        }
        public JsonResult Districtlist(string Id)
        {
            var districttype = from s in CascadingDropdowns.GetDistrictList()
                               where s.StateName == Id
                               select s;            
            return Json(new SelectList(districttype.ToArray(), "StateName", "DistrictName"), JsonRequestBehavior.AllowGet);
        }
    }
}

这是为了查看

@Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
    $(function () {
        $("State").change(function () {
            $.getJSON('/CascadeListController/Districtlist' + $('#State').val(), function (data) {
                var items = '<option>Select a District</option>';
                $.each(data, function (i, districttype) {
                    items += "<option value = '" + districttype.Value + "'>" + districttype.Text + " </option> ";
                });
                $('#District').html(items);
            });
        });
    });
</script>    
@model MvcSampleApplication.Models.CascadingDropdowns
@{
    ViewBag.Title = "BasicDrop";
}    
<h2>BasicDrop</h2>
@using (Html.BeginForm())
{
  <div>
    <fieldset>
    <legend>DropDownlists</legend>
      @Html.Label("State")
      @Html.DropDownList("State", ViewBag.StateName as SelectList,"Select A state", new {id= "State"})         
      @Html.Label("District");       
      <div class="mycombo">
         <select id ="District" name ="Distrct"></select>
      </div>            
    </fieldset>
  </div>
}

当我在第一个下拉列表中选择项目时,我无法在第二个下拉列表中看到任何项目,并且我已将 div 属性用于第二个下拉列表以增加宽度,我已指定宽度,例如“70px”,但它也不起作用..

请任何人对此提出任何建议...非常感谢。

4

3 回答 3

1

网址中有两件事是错误的:

  • 缺少斜线“/”分隔动作名称和 ID,
  • 应从 中删除“控制器”一词CascadeListController

$.getJSON('/CascadeList/Districtlist/'+ $('#State').val(),

此外,建议使用Url.Content将虚拟服务器端路径转换为 ​​url:

$.getJSON('@Url.Content("~/CascadeList/Districtlist/")'+ $('#State').val(),

于 2013-07-25T15:47:20.937 回答
0

这是一个可以为您工作的解决方案。我已将您的代码更改为我觉得很舒服的代码,并尝试遵循最佳实践。编辑它以适应您的场景。我从不使用ViewBag,也从不使用SelectList.

I will be answering this question based on my assumption that when a state is selected then all that state's districts will be loaded in a another drop down.

去创建名为Stateand的领域模型类District。这将代表您所有的州和地区。

public class State
{
     public int Id { get; set; }

     public string Name { get; set; }
}

public class District
{
     public int Id { get; set; }

     public string Name { get; set; }
}

您将拥有一个视图模型,您将在控制器中填充数据,然后将此视图模型传递给您的视图。如果您需要捕获其他数据,您的视图模型可以包含其他属性。

public class LocationViewModel
{
     public int StateId { get; set; }

     public IEnumerable<State> States { get; set; }

     public int DistrictId { get; set; }

     public IEnumerable<District> Districts { get; set; }
}

现在您需要使用数据填充视图模型并将其传递给视图。您将传入所有州的列表和一个空的地区列表。

public class CascadeListController : Controller
{
     private readonly IStateRepository stateRepository;
     private readonly IDistrictRepository districtRepository;

     public LocationController(IStateRepository stateRepository, IDistrictRepository districtRepository)
     {
          this.stateRepository = stateRepository;
          this.districtRepository = districtRepository;
     }

     public ActionResult Create()
     {
          LocationViewModel viewModel = new LocationViewModel
          {
               States = stateRepository.GetAll(),
               Districts = Enumerable.Empty<District>() // Empty because no state has been selected
          };

          return View(viewModel);
     }

     [HttpPost]
     public ActionResult Create(LocationViewModel viewModel)
     {
          // Do whatever you need to do here
     }
}

您的视图是强类型的:

@model YourProject.ViewModels.Locations.LocationViewModel

@Html.DropDownListFor(
     x => x.StateId,
     new SelectList(Model.States, "Id", "Name", Model.StateId),
     "-- Select --",
     new { id = "States" }
)
@Html.ValidationMessageFor(x => x.StateId)

@Html.DropDownListFor(
     x => x.DistrictId,
     new SelectList(Model.Districts, "Id", "Name", Model.DistrictId),
     "-- Select --",
     new { id = "Districts" }
)
@Html.ValidationMessageFor(x => x.DistrictId)

您的 jQuery 来处理第二个下拉列表的更改和填充:

$(document).ready(function () {
     $("#Departments").change(function () {
          var url = '@Url.Action("GetDistrictsByStateId", "CascadeList")';
          var stateId = $("#States").val();

          $.getJSON(url, { stateId: stateId }, function (data) {
               $('#Districts').empty();
               var items = '<option>-- Select --</option>';

               $.each(data, function (i, district) {
                    items += "<option value='" + district.Id + "'>" + district.Name + "</option>";
               });

               $('#Districts').html(items);
          });
     });
});

最后是您的 GetDistrictsByStateId 操作方法,以恢复特定州的所有地区:

public ActionResult GetDistrictsByStateId(int stateId)
{
     IEnumerable<District> districts = districtRepository.GetDistrictsByStateId(stateId);

     var displayedDistricts = districts.Select(x => new
     {
          Id = x.Id.ToString(),
          Name = x.Name
     });

     return Json(displayedDistricts, JsonRequestBehavior.AllowGet);
}

可能还有其他方法可以做到这一点,但这对我来说是最容易做到的。如果我遗漏了什么,请原谅:)

我希望这可以帮助您走上正确的道路。

于 2013-07-26T08:28:42.947 回答
0
@Scripts.Render("~/bundles/jquery")
    <script type="text/javascript">
        $(function () {
            $("State").change(function () {
                $.getJSON('/CascadeList/Districtlist?id=' + $('#State').val(), function (data) { 
...    

        });
    });
});

您在传递查询字符串时缺少问号,我认为这是错误的。实现此目的的另一种方法是使用 $.getJSON 方法的数据参数

$.getJSON('/CascadeList/Districtlist', {id = $('#State').val()},
function (data) { 
    ...
});
我认为还有另一种方法可以直接在 url 和查询字符串之间使用正斜杠(虽然我不确定,必须测试它)
$.getJSON('/CascadeList/Districtlist/'+ $('#State').val(),
function (data) { 
    ...
});

编辑:在@Igor 指出之前,没有观察到控制器名称中的“控制器”关键字。

于 2013-07-25T15:17:34.680 回答