asp.net-mvc 如何使用另一个下拉列表过滤下拉列表的选项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10304489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:53:51  来源:igfitidea点击:

How to filter the options of a drop down list using another drop down list

asp.net-mvcasp.net-mvc-3razor

提问by Sophonias

I am very new to ASP.NET and I am using the MVC 3 framework of ASP.Net. I was trying to filter the options of a dropdown list using another drop down and I can't manage to do that. I was trying to do this first by populating both the list of main categories and and sub categories and loading them to the page.Then setting the class attribute of the options of each sub-category to their parent category. Finally on the click of the parent category from the first dropdown list only show the child sub-category and hide the rest(This is how i did it previously in java). But in ASP.Net MVC the html code is so different i can't even set the class attribute for each option of the dropdown it generally sets the class for all the drop downs not for each option. This is what I have right now This is my View

我对 ASP.NET 很陌生,我正在使用 ASP.Net 的 MVC 3 框架。我试图使用另一个下拉列表过滤下拉列表的选项,但我无法做到这一点。我试图通过填充主类别和子类别的列表并将它们加载到页面来首先尝试执行此操作。然后将每个子类别的选项的类属性设置为它们的父类别。最后单击第一个下拉列表中的父类别只显示子子类别并隐藏其余部分(这是我以前在 java 中所做的)。但是在 ASP.Net MVC 中,html 代码是如此不同,我什至无法为下拉列表的每个选项设置类属性,它通常为所有下拉列表而不是每个选项设置类。这就是我现在拥有的 这是我的观点

<p>
@Html.LabelFor(model => model.CategoryId)
@Html.DropDownListFor(x => x.CategoryId , new SelectList(Model.Categories, "CategoryId", "CategoryName"), new { onchange= "this.form.submit();"})
</p>

<p>
@Html.LabelFor(model => model.SubCategories)
@Html.DropDownListFor(x => x.SubCategories, new SelectList(Model.SubCategories, "SubCategoryId", "SubCategoryName"), new { @class = "Category1.categoryname" })
 </p>

This is my model

这是我的模型

public class TestQuestionsViewModel
{
    public string CategoryId { get; set; }
    public IEnumerable<Category> Categories { get; set; }

    public string SubCategoryId { get; set; }
    public IEnumerable<SubCategory> SubCategories { get; set; }
 }

This is my controller class method

这是我的控制器类方法

    public ActionResult Create()
    {

        var model = new TestQuestionsViewModel
        {

            Categories = resetDB.Categories.OrderBy(c => c.categoryid),
            SubCategories = resetDB.SubCategories.OrderBy(sc => sc.subcategoryid)
         };
     return View(model);
    }

My questions is How can i set the class attributes for each individual options. Or if anyone has a suggestion on how to do this in a different way I am open for any solution. Thank you.

我的问题是如何为每个单独的选项设置类属性。或者,如果有人对如何以不同的方式执行此操作有任何建议,我愿意接受任何解决方案。谢谢你。

回答by Shyju

Loading all the Sub Items to the page when the page loads initially, does not seems to be a good idea to me. What if you have 100 Categories and Each categories has 200 sub category items ? Do you really want to load 20000 items ?

在页面最初加载时将所有子项目加载到页面上,对我来说似乎不是一个好主意。如果您有 100 个类别并且每个类别有 200 个子类别项目怎么办?你真的要加载 20000 个项目吗?

I think you should do an incremental way of loading. Provide the Main Category dropdown with the values, Let the user selects one item from that. Make a call to the Server and get the Sub categories belongs to the selected category and load that data to the second dropdown. You can use jQuery ajax to do it so that user will not feel a complete page reload when he select one drop down. This is how i will do it.

我认为您应该采用增量加载方式。为 Main Category 下拉列表提供值,让用户从中选择一项。调用服务器并获取属于所选类别的子类别并将该数据加载到第二个下拉列表。您可以使用 jQuery ajax 来做到这一点,这样用户在选择一个下拉列表时就不会感觉到一个完整的页面重新加载。这就是我将如何做到的。

Create the ViewModel which has both category properties

创建具有两个类别属性的 ViewModel

public class ProductViewModel
{
    public int ProductId { set;get;}
    public IEnumerable<SelectListItem> MainCategory { get; set; }
    public string SelectedMainCatId { get; set; }
    public IEnumerable<SelectListItem> SubCategory { get; set; }
    public string SelectedSubCatId { get; set; }
}

Let your GET Action method returns this strongly typed view with the content for MainCategory filled

让您的 GET Action 方法返回这个带有 MainCategory 内容的强类型视图

public ActionResult Edit()
{
   var objProduct = new ProductViewModel();             
   objProduct.MainCategory = new[]
   {
      new SelectListItem { Value = "1", Text = "Perfume" },
      new SelectListItem { Value = "2", Text = "Shoe" },
      new SelectListItem { Value = "3", Text = "Shirt" }
   };
   objProduct.SubCategory = new[] { new SelectListItem { Value = "", Text = "" } };
   return View(objProduct);
}

and in your strongly typed View,

在你的强类型视图中,

@model MvcApplication1.Models.ProductViewModel
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
@using (Html.BeginForm())
{    
    @Html.DropDownListFor(x => x.SelectedMainCatId, new SelectList(Model.MainCategory,"Value","Text"), "Select Main..")
    @Html.DropDownListFor(x => x.SelectedSubCatId, new SelectList(Model.SubCategory, "Value", "Text"), "Select Sub..")    
    <button type="submit">Save</button>
}
<script type="text/javascript">
    $(function () {
        $("#SelectedMainCatId").change(function () {
            var val = $(this).val();
            var subItems="";
            $.getJSON("@Url.Action("GetSub","Product")", {id:val} ,function (data) {
              $.each(data,function(index,item){
                subItems+="<option value='"+item.Value+"'>"+item.Text+"</option>"
              });
              $("#SelectedSubCatId").html(subItems)
            });
        });
    });
</script>

Add GetSub action method to your controller to return the sub categories for the selected category. We are returning the response as Json

将 GetSub 操作方法添加到您的控制器以返回所选类别的子类别。我们以 Json 的形式返回响应

 public ActionResult GetSub(int id)
 {
    List<SelectListItem> items = new List<SelectListItem>();
    items.Add(new SelectListItem() { Text = "Sub Item 1", Value = "1" });
    items.Add(new SelectListItem() { Text = "Sub Item 2", Value = "8"});
    // you may replace the above code with data reading from database based on the id

    return Json(items, JsonRequestBehavior.AllowGet);
 }

Now the selected values will be available in your HTTPOST Action method

现在所选值将在您的 HTTPOST 操作方法中可用

    [HttpPost]
    public ActionResult Edit(ProductViewModel model)
    {
        // You have the selected values here in the model.
        //model.SelectedMainCatId has value!
    }

回答by McGarnagle

You need to add another method to handle the postback and filter the sub-category options. Something like this:

您需要添加另一种方法来处理回发并过滤子类别选项。像这样的东西:

[HttpPost]
public ActionResult Create(TestQuestionsViewModel model)
{
    model.SubCategories = resetDB.SubCategories
            .Where(sc => sc.categoryid == model.SubCategoryId)
            .OrderBy(sc => sc.subcategoryid);
    return View(model);    
}

Edit

编辑

Btw, if you still need to set the class name to the other drop-down, you can't do it like that. The easiest way would by to add a "SelectedCategoryName" property to your model, and reference like { @class = ModelSelectedCategoryName }.

顺便说一句,如果您仍然需要将类名设置为另一个下拉列表,则不能这样做。最简单的方法是将“SelectedCategoryName”属性添加到您的模型中,并像{ @class = ModelSelectedCategoryName }一样引用。