【问题标题】:3 Dropdown List cascade using MVC3 & LinqSql3 使用 MVC3 & LinqSql 的下拉列表级联
【发布时间】:2011-08-01 13:33:34
【问题描述】:

我有 3 个下拉列表,我想用级联制作 3 个下拉列表。我正在将 LinqSql 用于数据库..

我有 3 个表 Product(id,name), Design(id,master_id,name), Model(id,design_id,name) master_id 绑定到 Product(id),design_id 绑定到 Design(id)..

我想创建一个显示产品的下拉菜单,而不是当我选择产品时,它会启用设计下拉菜单,否则它将保持禁用状态。这也是我无法解决的棘手部分,我需要很好的解释在这里创建第三个下拉菜单,在选择设计之前,该下拉菜单将被正常禁用。

他们每个人都会填充一个绑定到他们的较低下拉列表。就像; 产品将启用并填充设计, 设计将启用和填充模型。 我可以用 2 个下拉菜单来做到这一点,但是当涉及 3 个下拉菜单时,我真的很糟糕(大脑冻结)..

我已经检查了其他问题,找不到适合我自己的任何解决方案。正如我所说,我正在使用 LinqSql,我需要一个关于 3 级联下拉列表的解决方案来实现这种类型的数据范围。

已经感谢您所做的一切!如果你能解释模型-视图-控制器部分和参数以及为什么使用它们,那就太棒了。我是这个 MVC3 的初学者。

【问题讨论】:

  • 关于 json 我也学会了如何使用 json,但在 get 和 set 部分仍然遇到一些问题,对这些部分进行一些解释会让我很开心。
  • 它应该(几乎)完全相同 - 您将发送一个 AJAX 请求,其中从第二个下拉列表中选择的值作为参数,并在返回处理程序中启用/填充第三个下拉列表.如果您在某个特定步骤遇到问题,请更详细地描述确切的问题。
  • 我看到有些人这样做 所以我能够以这种方式填充第二个,但是当涉及到第三个时,我不知道该怎么办!实际上我不知道如何调用元素
  • 我的问题是控制器模型视图关系我仍然无法习惯.. jquery 和 ajax 请求我真的没有问题..
  • 听起来你把事情复杂化了——我很困惑你想弄清楚什么。 IE。听起来您想知道如何使用下拉列表中的选定值调用方法,但随后您说那部分没有问题。您能否发布一些示例代码来说明您的故障所在?

标签: c# linq-to-sql asp.net-mvc-3 jquery cascadingdropdown


【解决方案1】:

我会这样处理问题:

首先,在控制器中,我们将设置以下方法:

public JsonResult GetDesignsForProduct(int productId)
{
  // Instantiate our context and do whatever goo we need to select the objects we want
  using (MyDatabaseContext ctx = new MyDatabaseContext())
  {
     return Json(ctx.Designs.Where(d => d.master_id == productId).ToList(), JsonRequestBehavior.AllowGet);
  }
}

public JsonResult GetModelsForDesign(int designId)
{
  // Instantiate our context and do whatever goo we need to select the objects we want
  using (MyDatabaseContext ctx = new MyDatabaseContext())
  {
     return Json(ctx.Models.Where(d => d.design_id == designId).ToList(), JsonRequestBehavior.AllowGet);
  }
}

我在这里打开了“获取”;如果您的数据包含敏感信息 - 用户名/电子邮件地址、其他专有或受法律保护的数据等 - 您可以将其更改为仅允许“发布”,并相应地修改您的 Javascript。见Phil Haack's article

另外,如果您希望此数据经常更改,这些方法将默认根据您的应用程序的缓存设置对其进行缓存。您可以在方法上添加OutputCache 属性来改变这种行为。

然后,在视图中,您将拥有一些 AJAX 管道,如下所示:

function LoadDesigns() {
    // Get the currently-selected value in our Product dropdown
    var prod = $("#Product").val();

    // Call our controller method and process the list of Design objects
    $.getJSON('@Url.Content("~/ControllerName/GetDesignsForProduct")', { productId: prod },
        function (designs) {
            $("#Design").empty();
            $.each(designs, function (i, c) {
                $("#Design").append(
                    $('<option></option>').val(c.id).html(c.name)
                );
            });
    });
}

function LoadModels() {
    // Get the currently-selected value in our Design dropdown
    var des = $("#Design").val();

    // Call our controller method and process the list of Model objects
    $.getJSON('@Url.Content("~/ControllerName/GetModelsForDesign")', { designId: des },
        function (models) {
            $("#Model").empty();
            $.each(models, function (i, c) {
                $("#Model").append(
                    $('<option></option>').val(c.id).html(c.name)
                );
            });
    });
}

最后,如下定义所有三个下拉菜单:

@Html.DropDownList("Product", productSelectList, new { onchange = "LoadDesigns()" })
@Html.DropDownList("Design", null, new { onchange = "LoadModels()" })
@Html.DropDownList("Model")

不要忘记 HTML 帮助程序实际上只是生成底层 HTML 的快捷方式,在 Razor 中,您经常直接进入 HTML 而不是与帮助程序混淆。因此,您可以像这样轻松地编写这些:

<select id="Product" onchange="LoadDesigns()">
  @foreach (var prod in products) {
    <option value="@prod.id">@prod.name</option>
  }
</select>

<select id="Design" onchange="LoadModels()"></select>

<select id="Model"></select>

【讨论】:

  • 非常感谢,现在我明白了下拉和分离每个下拉控制器是一个真正的好主意,我只使用了一个。我猜这是我的问题,并且再次显示每个部分的扩展关于参数使用的知识..它真的很有帮助。
  • 我想添加 smt,如果其中一个表没有可枚举项,同时填充下拉列表会发生什么情况..
  • 你的意思是,如果没有匹配外键?它将返回一个空列表,因此您将有一个空的下拉列表。如果你想修改这个行为,你可以在 Controller 方法中检测到它并返回一个列表,其中包含一些半有用的东西。
【解决方案2】:

忘记设置我完成的工作..人们可能想看看它是如何发生的.. 这是我的:

视图 + Jquery

$(function () {
    $("select#Design").attr('disabled', 'true');
    $("select#Model").attr('disabled', 'true');

    $("select#Product").click(function () {
        var prod = $("select#Product option:selected").val();
        if (prod == "" || prod == 0) {
            $("select#Design").attr('disabled', 'true');
            $("select#Model").attr('disabled', 'true');
        } else {
            $.getJSON('@Url.Content("~/Admin/GetDesigns/")', { productId: prod }, function (data) {
                $("select#Design").empty();
                $("select#Model").empty();
                $.each(data, function (i, c) {
                    $('select#Design').append('<option value="' + c.Value + '">' + c.Text + '</option>');
                })
                $("select#Design").removeAttr('disabled');
                $("select#Design option:first").attr('selected', 'selected');

                var des = $("select#Design option:selected").val();
                if (des == "" || des == 0) {
                    $("select#Model").attr('disabled', 'true');
                } else {
                    $.getJSON('@Url.Content("~/Admin/GetModels/")', { designId: des }, function (data) {
                        $("select#Model").empty();
                        $.each(data, function (i, c) {
                            $('select#Model').append('<option value="' + c.Value + '">' + c.Text + '</option>');
                        })
                        $("select#Model").removeAttr('disabled');
                        $("select#Model option:first").attr('selected', 'selected');
                     })
                  }
               })
            }
         })
     })

原因我以这种方式使用 Jquery 来填充所有下拉菜单并选择第一个元素作为默认选择!当我从第一个下拉列表中选择一个元素时,其他两个下拉列表开始填充自己并选择它们的第一个元素作为默认选择。相同的代码可用于其他下拉列表单击功能,如下所示:

            $("select#Design").click(function () {
                var des = $("select#Design option:selected").val();
                if (des == "" || des == 0) {
                    $("select#Model").attr('disabled', 'true');
                } else {
                    $.getJSON('@Url.Content("~/Admin/GetModels/")', { designId: des }, function (data) {
                        $("select#Model").empty();
                        $.each(data, function (i, c) {
                            $('select#Model').append('<option value="' + c.Value + '">' + c.Text + '</option>');
                        })
                        $("select#Model").removeAttr('disabled');
                        $("select#Model option:first").attr('selected', 'selected');
                    })
                }
           });

查看

@using (Html.BeginForm("Index", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table>
    <tr>
        <td style="background-color:#e8eef4;" rowspan="3">
        </td>
        <td style="width:190px; background-color:#e8eef4;">
            @Html.DropDownList("Product", (SelectList)ViewData["ProductList"], "Please Select Product", new { style = "width:190px; padding:4px; margin:4px;" })
        </td>
        <td rowspan="3" style="width:400;">
        </td>
        <td style="background-color:#e8eef4;">
        </td>
        <td style="background-color:#e8eef4;" rowspan="3">
        </td>
    </tr>
    <tr>
        <td style="background-color:#e8eef4;">
            <select id="Design" style="width:190px; padding:4px; margin:4px;">
            <option label="Please Select Design" selected="selected"></option>
            </select>
        </td>
        <td style="background-color:#e8eef4;">
        </td>
    </tr>
    <tr>
        <td style="background-color:#e8eef4;">
            <select id="Model" style=" width:190px; padding:4px; margin:4px;">
            <option label="Please Select Model"></option>
            </select>
        </td>
        <td style="background-color:#e8eef4;">
        </td>
    </tr>
</table>
}

只是因为我使用 linqtosql 而我懒得做一个存储库.. 这是我的控制器

public class AdminController : Controller
{
    public linqVipDataContext db = new linqVipDataContext();

    //
    // GET: /Admin/
    public ActionResult Index()
    {
        IEnumerable<SelectListItem> ProductItems = db.Products.AsEnumerable().Select(c => new SelectListItem()
        {
            Text = c.name,
            Value = c.id.ToString(),
            Selected = true,
        });
        SelectList prod = new SelectList(ProductItems, "Value", "Text");
        ViewBag.ProductList = prod;
        return View();
    }


    //
    //Fill the Design List..
    public JsonResult GetDesigns(int productId)
    {
        /*var data = dbs.Designs.Where(d => d.master_id == productId).ToList();*/

        IEnumerable<SelectListItem> DesignItems = db.Designs.Where(c => c.master_id == productId).AsEnumerable().Select(c => new SelectListItem()
        {
            Text = c.name,
            Value = c.id.ToString()
        });
        SelectList des = new SelectList(DesignItems, "Value", "Text");
        return Json(des, JsonRequestBehavior.AllowGet);
    }

    //
    //Fill the Model List..
    public JsonResult GetModels(int designId)
    {   
        /*This code down here! Doesnt work and says it's type is unknown*/
        /*var data = dbs.Models.Where(d => d.design_id == designId).ToList();*/

        /*For that reason im using this code*/
        IEnumerable<SelectListItem> ModelItems = db.Models.Where(d => d.design_id == designId).AsEnumerable().Select(c => new SelectListItem()
        {
            Text = c.name,
            Value = c.id.ToString()
        });
        SelectList mods= new SelectList(ModelItems, "Value", "Text");
        return Json(mods, JsonRequestBehavior.AllowGet);
    }

Json 需要将 Value 和 Text 2 参数分开来创建一个选择列表选项。所以我必须以这种方式返回我的值。

我发布了这个,因为我在你的代码中发现了一些故障,再次向我展示了这个解决方案,它给了我这个想法并让我解决了所有问题,所以这是完全工作的代码。再次 Ty。希望它有用。

【讨论】:

    猜你喜欢
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多