【问题标题】:MVC 4 Ajax DropDownListMVC 4 Ajax 下拉列表
【发布时间】:2017-10-25 13:22:13
【问题描述】:

一个表单上有两个 DropDownList。

如果用户在第一个 DropDownList 中选择了一个 Region,那么在第二个 DropDownList 中应该只有与该区域相关的城市。

我已经尝试过在 StackOverflow 上找到的解决方案,但是由于我对 jQuery 和 MVC 的初学者知识,我失败了。也许我的模型/控制器和其他模型/控制器之间存在差异,这些 DropDownLists 已经在表单上,​​应该使用 ajax 动态更改它们。

HTML

<div class="form-group col-sm-4">
    @Html.LabelFor(m => m.Company.Region.Name)
    @Html.DropDownList("region", Model.Regions, new { @class = "form-control" ,@id = "Region_drop" })
</div>

<div class="form-group col-sm-4">
    @Html.LabelFor(m => m.Company.City.Name)
    @Html.DropDownList("city", Model.Cities, new { @class = "form-control" ,@id = "City_drop" })
</div>

控制器

[Authorize]
public ActionResult AddCompany()
{
    CompanyModel company = new CompanyModel();
    SelectList regions = new SelectList(db.Regions, "Id", "Name");
    SelectList cities = new SelectList(db.Cities, "Id", "Name");

    AddCompanyViewModel acvm = new AddCompanyViewModel
    {
        Regions = regions,
        Cities = cities,
    };

    return View(acvm);
}

型号

public class RegionModel
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Display(Name = "Регион")]
    [Required]
    public string Name { get; set; }

    public IEnumerable<CompanyModel> Companies { get; set; }
    public IEnumerable<CityModel> Cities { get; set; }
}

public class CityModel
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Display(Name = "Город")]
    [Required]
    public string Name { get; set; }

    public int RegionId { get; set; }
    public RegionModel Region { get; set; }

    public IEnumerable<CompanyModel> Companies { get; set; }
}

更新: 我尝试编写辅助 ActionResult 以从 DB 获取数据

[HttpPost]
public ActionResult getCitiesAction(int provinceId)
{
    var cities = db.Cities.Where(a => a.RegionId == provinceId).Select(a => "<option value='" + a.Id + "'>" + a.Name + "'</option>'");

    return Content(String.Join("", cities));
}

然后按照其他解决方案之一的建议添加了一些 JS:

$("#Region_drop").change(function () {
  $.ajax({
    url: "getCitiesAction",
    type: "post",
    data: {
      provinceId: $("#Region_drop").val()
    }
  }).done(function (response) {
    $("#City_drop").html(response);
  });
});

在浏览器中运行它并打断点后,它会显示区域 ID,但在调用 ajax 后,函数就死了。

【问题讨论】:

  • 请展示您尝试了什么以及它是如何失败的——也许它离正常工作不远,可以轻松修复。目前没有证据表明,除了你的话,你确实试图这样做。
  • @ADyson 更新了问题,感谢您的回复。

标签: c# asp.net ajax asp.net-mvc


【解决方案1】:

虽然您的代码可以正常工作(除了它会在选项文本中添加一个额外的' 作为后缀,将 UI 标记与生成数据的 C# 代码混合并不是一个好主意。使用您当前的代码,您的操作方法正在生成呈现选项所需的字符串。

我建议不要在您的操作方法中为您的选项标记构建字符串。返回一个 json 数组。通过这种方式,如果您想使用相同的操作方法呈现表格行/div/列表项的列表,则可以使用相同的方法。您从服务器传输的有效负载也更少。

[HttpPost]
public ActionResult getCitiesAction(int provinceId)
{
    var cities = db.Cities
                   .Where(a => a.RegionId == provinceId)
                   .Select(a => new SelectListItem { Value=a.Id.ToString(), Text=a.Name})
                   .ToList()

    return Json(cities);
}

现在在您的 ajax done 事件中,循环遍历此数组并创建一个选项项,设置 text 和 value 属性值并将其添加到 SELECT 元素中

).done(function (response) {
    $("#City_drop").empty();
    $.each(response,function(i,item)
    {
        $("#City_drop").append($("<option>").text(item.Text).val(item.Value));
    });   
});

【讨论】:

  • &lt;li&gt; 对于下拉列表(&lt;select&gt; 元素)应该是 &lt;option&gt;,不是吗?
  • 是的。马上解决。谢谢
  • @Shyju 能否请您建议如何使此功能从 $(document).ready 开始工作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多