无法在视图中的第二个下拉列表中获取值

时间:2013-07-25 13:48:28

标签: c# asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 razor

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

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属性作为第二个下拉列表来增加宽度,我指定了宽度,如&#39; 70px&# 39;但它也不起作用..

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

3 个答案:

答案 0 :(得分:1)

网址中出现两个错误:

  • 缺少斜杠“/”分隔操作名称和ID,
  • 字词“Controller”应从CascadeListController
  • 中删除

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

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

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

答案 1 :(得分: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和query-string之间使用正斜杠(尽管我不确定,必须测试它)
$.getJSON('/CascadeList/Districtlist/'+ $('#State').val(),
function (data) { 
    ...
});

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

答案 2 :(得分:0)

这是一个适合您的解决方案。我已经将您的代码更改为我感觉舒服的内容,并且我尝试遵循最佳实践。编辑它以适应您的方案。我从不使用ViewBag,我从不使用SelectList

我将基于我的假设来回答这个问题,即当选择一个州时,所有州的区域将被加载到另一个州。

转到并创建名为StateDistrict的域模型类。这将代表您所有的州和地区。

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

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

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