ASP.NET MVC 级联下拉菜单

Posted

技术标签:

【中文标题】ASP.NET MVC 级联下拉菜单【英文标题】:ASP.NET MVC cascading dropdown 【发布时间】:2018-04-25 10:18:56 【问题描述】:

我的数据库中有如下三个表:

University 
 id   Name
 1     A
 2     B

Faculty 
id   id_uni   name
1      1       AA
2      1       AA

cafedry
id    id_uni    id_faculty   name

1       1            1        cc

我想创建一个级联下拉列表,让我可以先选择大学,然后选择学院,然后选择 Cafedry。下面的代码是我迄今为止尝试过的。

 public ActionResult Create()
    
        ViewBag.fak_kod = new SelectList(db.Fakulteler, "id", "adi");
        ViewBag.unikod = new SelectList(db.Universitetler, "id", "adi");
        return View();
    

    // POST: kafedras/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "id,unikod,fak_kod,adi")] kafedra kafedra)
    
        if (ModelState.IsValid)
        
            db.kafedra.Add(kafedra);
            db.SaveChanges();
            return RedirectToAction("Index");
        

        ViewBag.fak_kod = new SelectList(db.Fakulteler , "id", "adi", kafedra.fak_kod);
        ViewBag.unikod = new SelectList(db.Universitetler, "id", "adi", kafedra.unikod);
        return View(kafedra);
    

还有这个cshtml

<div class="form-horizontal">
    <h4>kafedra</h4>
    <hr />
    @Html.ValidationSummary(true, "", new  @class = "text-danger" )
    <div class="form-group">
        @Html.LabelFor(model => model.unikod, "unikod", htmlAttributes: new  @class = "control-label col-md-2" )
        <div class="col-md-10">
            @Html.DropDownList("unikod", null, htmlAttributes: new  @class = "form-control" )
            @Html.ValidationMessageFor(model => model.unikod, "", new  @class = "text-danger" )
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.fak_kod, "fak_kod", htmlAttributes: new  @class = "control-label col-md-2" )
        <div class="col-md-10">
            @Html.DropDownList("fak_kod", null, htmlAttributes: new  @class = "form-control" )
            @Html.ValidationMessageFor(model => model.fak_kod, "", new  @class = "text-danger" )
        </div>
    </div>

如何更新此代码以创建包含三个表的级联下拉列表?

【问题讨论】:

所以你想实现级联下拉? 是的,实际上让我在下拉菜单中手动选择,但我想要级联,例如选择大学 AA,然后在教员中 dropdwon 显示哪些教员在大学中拥有一个 看看这个***.com/questions/46954959/… 看过但没有帮助我 为什么[cafedry]表中需要[id_uni]? [cafedry] 表和 [University] 表之间的链接通过 [Faculty] 表存在 【参考方案1】:

首先,创建一个视图模型,该模型具有呈现选项和存储所选项目值的属性。

public class CreateVm

   [Required]
   public int SelectedUniversity  set;get;

   [Required]
   public int SelectedFaculty  set;get;  

   public List<SelectListItem> Universities  set;get;    
   public List<SelectListItem> Faculties  set;get;

   public CreateVm()
   
       this.Faculties = new List<SelectListItem>();
       this.Universities = new List<SelectListItem>();
     

现在在您的 GET 操作中,创建 this 的对象,加载 Universities 属性并将对象发送到视图

public AcitonResult Create()
 
   var vm=new CreateVm();
   vm.Universities= GetUniversities();
   return View(vm);

private List<SelectListItem> GetUniversities()

    return db.Universitetler
             .Select(x=>new SelectListItem  Value = x.Id,
                                             Text = x.Name)
             .ToList();

现在在您的视图中,这是我们CreateVm 视图模型的强类型。我们将使用DropDownListFor 辅助方法来呈现下拉菜单

@model CreateVm
@using (Html.BeginForm("Create", "Home"))

   @Html.DropDownListFor(a=>a.SelectedUniversity,Model.Universities,"Select one")
   @Html.DropDownListFor(a => a.SelectedFaculty , Model.Faculties, "Select one",
                                       new  data_url = Url.Action("GetFaculties") )
   <input type="Submit" />

这将呈现 2 个下拉菜单,一个带有大学选项,第二个将是空的(因为我们没有向 Faculties 属性加载任何内容)。现在我们将有一些 javascript(我们在这里使用 jquery 以方便 DOM 操作)将监听第一个下拉列表(Universities)的更改事件,读取选定的值并对 GetFaculties 方法进行 ajax 调用和通过选定的大学选项值。

您可以看到,我为第二个下拉列表设置了一个 html5 数据属性,我在其中将相对 url 存储到 GetFaculties 方法。所以在我的javascript中,我可以简单地读取这个数据属性值并调用那个url来获取数据。

$(function () 
    $("#SelectedUniversity").change(function () 
        var v = $(this).val();
        var url = $("#SelectedFaculty").data("url") + '?u=' + v;
        var $fac= $("#SelectedFaculty");
        $.getJSON(url, function (data) 
                $fac.empty();
                $.each(data, function (i, item) 
                    $fac.append($("<option>").text(item.Text).val(item.Value));
                );
            );    
    );
);

现在,让我们添加一个 GetFaculties 操作方法,它接受大学 ID 并在 SelectListItem 列表中以 JSON 数组的形式返回该大学的学院。

public ActionResult GetFaculties(int u)

    var facultyList = db.Fakulteler
                        .Where(a=>a.id_uni==u)
                        .Select(x=>new SelectListItem  Value=x.Id,
                                                       Text=x.Name).ToList();
    return Json(facultyList , JsonRequestBehavior.AllowGet);

您可以在 HttpPost 操作中使用相同的视图模型

[HttpPost]
public ActionResult Create(CreateVm vm)

    if (ModelState.IsValid)
    
        //read from vm and save
        var k=new kafedra  
                           UniveristyId=vm.SelectedUniversity, 
                           FacultyId=vm.SelectedFaculty, 
                        ;
        db.kafedra.Add(k);
        db.SaveChanges();
        return RedirectToAction("Index");
    
    vm.Universities= GetUniversities();
    return View(vm);

【讨论】:

非常感谢。但我在 ASP 网络表单中看到很容易给出这个结果 不错。我唯一推荐的是使用 JQuery 而不是 Javascript 来避免回发。

以上是关于ASP.NET MVC 级联下拉菜单的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 多选下拉菜单

如何在 Asp.NET MVC 中使用复选框创建多选下拉菜单

级联下拉菜单在 mvc 中返回未定义

为啥 Bootstrap 不允许我在 ASP.NET MVC 页面中的下拉菜单上设置边距?

任何人都有一些用于 asp.net mvc 的下拉日期选择器

使用 Json 和 Jquery 的 Asp.net MVC4 中的级联下拉列表不填充