Каскадный выпадающий список с mvc и jQuery не работает - PullRequest
0 голосов
/ 07 декабря 2010

Я пытаюсь использовать решение для каскадного раскрывающегося списка (выбор в одном раскрывающемся списке определяет параметры во втором), найденного здесь:

http://www.pieterg.com/post/2010/04/12/Cascading-DropDownList-with-ASPNET-MVC-and-JQuery.aspx

<script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            //Hook onto the MakeID list's onchange event
            $("#CustomerId").change(function () {
                //build the request url
                var url = "Timesheet/Tasks";
                //fire off the request, passing it the id which is the MakeID's selected item value
                $.getJSON(url, { id: $("#CustomerId").val() }, function (data) {
                    //Clear the Model list
                    $("#TaskId").empty();
                    //Foreach Model in the list, add a model option from the data returned
                    $.each(data, function (index, optionData) {
                        $("#TaskId").append("<option value='" + optionData.ID + "'>" + optionData.Description + "</option>");
                    });
                });
            }).change();
        });
    </script>
    <h2>
        Index</h2>
    <fieldset>
        <legend>Fields</legend>
        <div>
            <label for="Customers">
                Kund:</label>
            <%:Html.DropDownListFor(m => m.Customers, new SelectList(Model.Customers,"Id", "Name"), new {@id="CustomerId"}) %>
            <%--<%:Html.DropDownListFor(m => m.CustomerId, new SelectList(Model.Customers,"Id", "Name")) %>--%>
            &nbsp;&nbsp;
            <label for="Tasks">
                Aktiviteter:</label>
            <%:Html.DropDownListFor(m => m.Tasks, new SelectList(Model.Tasks,"Id", "Name"), new {@id="TaskId"}) %>
            <%--<%:Html.DropDownListFor(m => m.TaskId, new SelectList(Model.Tasks,"Id", "Name")) %>--%>
<%--            <select id="TaskId" name="TaskId">
            </select>--%>
        </div>
    </fieldset>

ИВот метод Action, который получает задачи:

    public JsonResult Tasks(string id)
    {
        var result = new JsonResult();
        //var tasks = from t in _model.Tasks
        //            where t.CustomerId.ToString() == id
        //            select t;
        List<Task> tasklist = new List<Task>();
        foreach (var task in _model.Tasks)
        {
            if(task.CustomerId.ToString() == id)
                tasklist.Add(task);
        }

        //result.Data = tasks.ToList();
        result.Data = tasklist;

        result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        return result;
    }

У меня есть две проблемы:

  1. Второй выпадающий список вообще не меняется в зависимости от первого.Я испробовал все виды вариантов (как вы можете видеть из закомментированных выпадающих списков).Я получаю сообщение об ошибке в Firebug, но не могу его интерпретировать (см. Ниже).
  2. Выражение linq в методе Action, похоже, не работает по какой-то причине, что действительно странно, потому чтоРаньше я использовал такие выражения без проблем.Может быть, я устала и что-то упустила, но не вижу этого.Выражение возвращает все задачи, а не только те, чей идентификатор совпадает с текущим клиентом.Foreach работает отлично, что делает его еще более странным ... Это совершенно не связано с первой проблемой, потому что опять же, foreach работает нормально и выбирает только три задачи (что правильно).Но все же второй выпадающий список показывает все задачи ...

Любая помощь приветствуется!

Журнал ошибок Firebug:

<code><html>
    <head>
        <title>A circular reference was detected while serializing an object of type 'Tidrapportering.Models.Task'.</title>
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
         pre {font-family:"Lucida Console";font-size: .9em}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
        </style>
    </head>

    <body bgcolor="white">

            <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>

            <h2> <i>A circular reference was detected while serializing an object of type 'Tidrapportering.Models.Task'.</i> </h2></span>

            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

            <b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

            <br><br>

            <b> Exception Details: </b>System.InvalidOperationException: A circular reference was detected while serializing an object of type 'Tidrapportering.Models.Task'.<br><br>

            <b>Source Error:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code>

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.</code>

                  </td>
               </tr>
            </table>

            <br>

            <b>Stack Trace:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>

[InvalidOperationException: A circular reference was detected while serializing an object of type &#39;Tidrapportering.Models.Task&#39;.]
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1478
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +126
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1311
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +126
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1311
   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat) +26
   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat) +74
   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj) +6
   System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context) +458
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +39
   System.Web.Mvc.&lt;&gt;c__DisplayClass14.&lt;InvokeActionResultWithFilters&gt;b__11() +60
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +391
   System.Web.Mvc.&lt;&gt;c__DisplayClass16.&lt;InvokeActionResultWithFilters&gt;b__13() +61
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +285
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +830
   System.Web.Mvc.Controller.ExecuteCore() +136
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +111
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +39
   System.Web.Mvc.&lt;&gt;c__DisplayClass8.&lt;BeginProcessRequest&gt;b__4() +65
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass1.&lt;MakeVoidDelegate&gt;b__0() +44
   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass8`1.&lt;BeginSynchronous&gt;b__7(IAsyncResult _) +42

   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +141
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +54
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +52
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8841105

   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +184

Информация о версии: Microsoft .NET Framework Версия: 4.0.30319;ASP.NET версия: 4.0.30319.1

ОБНОВЛЕНИЕ:

Теперь я обновил его до следующего:

Метод действиядля получения задач, связанных с выбранным клиентом:

    public JsonResult Tasks(string id)
    {
        var result = new JsonResult();
        var tasks =
            _model.Tasks.Where(task => task.CustomerId.ToString() == id).Select(
                task => new {ID = task.Id, Name = task.Name});
        result.Data = tasks;

        result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        return result;
    }

А в представлении:

    <div>
        <label for="Customers">
            Kund:</label>
        <%:Html.DropDownListFor(m => m.Customers, new SelectList(Model.Customers,"Id", "Name"), new {@id="CustomerId"}) %>
        &nbsp;&nbsp;
        <label for="Tasks">
            Aktiviteter:</label>
        <%:Html.DropDownListFor(m => m.Tasks, new SelectList(Model.Tasks,"Id", "Name"), new {@id="TaskId"}) %>
    </div>

Теперь я получаю результаты, как-то отфильтрованные и выбранные во втором раскрывающемся списке, количество параметровПравильно при выборе разных клиентов.Однако значение в раскрывающемся списке задач для всех них "неопределено" ...

ОБНОВЛЕНИЕ 2:

Я обнаружил проблему:

В jQuery у менязабыли исправить имена свойств объектов задачи.Вот рабочая версия:

    $(document).ready(function () {
        //Hook onto the MakeID list's onchange event
        $("#CustomerId").change(function () {
            //build the request url
            var url = "Timesheet/Tasks";
            //fire off the request, passing it the id which is the MakeID's selected item value
            $.getJSON(url, { id: $("#CustomerId").val() }, function (data) {
                //Clear the Model list
                $("#TaskId").empty();
                //Foreach Model in the list, add a model option from the data returned
                $.each(data, function (index, optionData) {
                    $("#TaskId").append("<option value='" + optionData.Id + "'>" + optionData.Name + "</option>");
                });
            });
        }).change();
    });

Но я хотел бы знать, как получить значение по умолчанию для выпадающих списков.Поскольку в противном случае выпадающий список клиента будет иметь значение, когда вы впервые попадете на страницу, а список задач не будет ...

1 Ответ

2 голосов
/ 07 декабря 2010

JsonResult использует JavascriptSerializer для генерации данных JSON, а JavascriptSerializer не поддерживает циклические ссылки. Возможно, следующий пост поможет вам решить вашу проблему: Исключение Json and Circular Reference

Обновление

Вместо того, чтобы обходить циклическую ссылку, просто верните список другого объекта с двумя необходимыми вам полями: ID и Description. Это будет выглядеть примерно так:

var tasklist = _model.Tasks.Where(x => x.CustomerId.ToString() == id)
                           .Select(x => new { ID = task.ID, Description = task.Description });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...