3 Каскад выпадающего списка с использованием MVC3 и LinqSql

У меня есть 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 каскадных выпадающих списках для этого типа доступа к данным.

спасибо уже за все, что вы можете сделать! и если вы можете объяснить партиалы и параметры Model-View-Controller и почему вы их используете, это было бы здорово. Я новичок в этом MVC3.


person Berker Yüceer    schedule 01.08.2011    source источник
comment
также о json я научился использовать json, но все еще есть некоторые проблемы с частями get и set, небольшое объяснение этих частей сделало бы мой день.   -  person Berker Yüceer    schedule 01.08.2011
comment
Он должен работать (почти) точно так же — вы отправляете запрос AJAX с выбранным значением из второго раскрывающегося списка в качестве параметра и включаете/заполняете третий раскрывающийся список в обработчике возврата. Если у вас возникли проблемы с конкретным шагом, опишите более подробно точную проблему.   -  person GalacticCowboy    schedule 01.08.2011
comment
я видел, как некоторые люди делают ‹select id=Product name=Product›, поэтому я сделал свой первый с выпадающим списком @html, а второй дизайн списка – ‹select id=design›, поэтому я смог заполнить второй таким образом, но когда дело доходит до третий не знаю что делать! на самом деле я не знаю, как вызвать элемент ‹select id=design›   -  person Berker Yüceer    schedule 01.08.2011
comment
моя проблема связана с отношениями представления модели контроллера, к которым я все еще не мог привыкнуть. У меня действительно нет проблем с запросами jquery и ajax.   -  person Berker Yüceer    schedule 02.08.2011
comment
Похоже, вы слишком усложняете вещи - я не понимаю, что вы пытаетесь понять. т.е. похоже, вы хотите знать, как вызвать метод с выбранным значением из раскрывающегося списка, но затем вы говорите, что у вас нет проблем с этой частью. Не могли бы вы опубликовать пример кода, который иллюстрирует, где вы ломаетесь?   -  person GalacticCowboy    schedule 02.08.2011
comment
Что касается вашего редактирования, на самом деле нет способа следовать каскадному подходу, если последней таблицей в каскаде является модель представления. Это связано с тем, что вы должны заполнить его до того, как будут заполнены предыдущие списки. Не только это, но и предыдущие списки будут содержать только родительские элементы из элементов в вашем третьем раскрывающемся списке, а не наоборот.   -  person GalacticCowboy    schedule 03.08.2011
comment
И с какой реальной проблемой вы сейчас сталкиваетесь?   -  person GalacticCowboy    schedule 04.08.2011
comment
вау, я написал это несколько десятилетий назад! и решено. Благодаря вам! nwm последний комментарий, который я оставил там .. я собираюсь удалить его сейчас. Спасибо за помощь..   -  person Berker Yüceer    schedule 19.03.2012


Ответы (2)


Я бы подошёл к проблеме примерно так:

Во-первых, в контроллере мы настроим следующие методы:

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. См. статью Фила Хаака.

Кроме того, если вы предполагаете, что эти данные будут часто изменяться, эти методы будут кэшировать их по умолчанию в соответствии с настройками кэша вашего приложения. Вы можете добавить к методу атрибут 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>
person GalacticCowboy    schedule 01.08.2011
comment
Большое спасибо, теперь я понимаю, что выпадающий список и разделение каждого контроллера выпадающих списков - это действительно хорошая идея, я использовал только один ... это была моя проблема, я думаю, а также еще раз, чтобы показать каждую часть с расширенными знаниями об использовании параметров ... его было действительно полезно. - person Berker Yüceer; 02.08.2011
comment
я хочу добавить smt, что произойдет, если в одной из таблиц нет перечисляемого элемента при заполнении раскрывающегося списка.. - person Berker Yüceer; 03.08.2011
comment
Вы имеете в виду, если ничего не соответствует внешнему ключу? Он вернет пустой список, поэтому у вас будет пустой раскрывающийся список. Если вы хотите изменить это поведение, вы можете обнаружить его в методе Controller и вернуть список, содержащий что-то полуполезное. - person GalacticCowboy; 03.08.2011

Забудьте установить мою готовую работу.. Люди могут захотеть увидеть, как это происходит.. Вот мой:

Просмотр + 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 снова. Надеюсь, это полезно.

person Berker Yüceer    schedule 09.08.2011