Kendo MVC Сетка, редактируемая, раскрывающееся каскадное раскрывающееся меню, отображающее 'undefined' - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь следовать демонстрации Telerik для каскадных выпадающих списков, но пока мне не повезло. Вот демонстрация, которую я пытаюсь использовать: Telerik Demo - каскадный DropDownList
Моя проблема в том, что когда я фильтрую контакты на основе ModelId (у меня другое имя, чем это), Я получаю выпадающее меню, просто говоря «undefined»

Вот мой код сетки (части, которые имеют значение)

@(Html.Kendo().Grid<MyViewModel>()
    .Name("grid")
    .AutoBind(false)
    .HtmlAttributes(new { @class = "grid-clickable-edit" })
    .Columns(columns =>
    {
        columns.Command(command =>
        {
            command.Edit().IconClass("fas fa-pencil").UpdateIconClass("fas fa-check").CancelIconClass("fas fa-ban");
            command.Destroy().IconClass("fas fa-trash");
        })
            .ClientHeaderTemplate(Html.GridAddButton())
            .Width(180);
        columns.Bound(p => p.ModelId)
            .EditorTemplateName("GridDropdownEditor")
            .EditorViewData(new { data = ViewBag.ModelList })
            .ClientTemplate("#:ModelName#");
        columns.Bound(p => p.ContactId)
            .EditorTemplateName("ContactCascadingDropdown")
            .ClientTemplate("#:ContactName#");
    })
    .Pageable(pg => pg.Numeric(false).PreviousNext(false))
    .Sortable()
    .Scrollable(scroll => scroll.Virtual(true))
    .Filterable(x => x.Enabled(false))
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Batch(true)
        .ServerOperation(true)
        .Model(model => { model.Id(m => m.MyId); })
        .Read(...)
        .Create(...)
        .Update(...)
        .Destroy(...)
    ))

<script>
    function filterContacts() {
        return {
            modelId: $("#ModelId").val()
        };
    }
</script>


Вот мой ContactCascadingDropdown шаблон редактора -

@model object

@(Html.Kendo().DropDownListFor(m => m)
    .DataTextField("ContactName")
    .DataValueField("ContactId")
    .DataSource(source =>
    {
        source.Read(read =>
        {
            read.Action("GetCascadingContacts", "ControllerName")
                .Data("filterContacts");
        })
            .ServerFiltering(true);
    })
    .Enable(false)
    .AutoBind(false)
    .CascadeFrom("ModelId"))


GetCascadingContacts метод из MyController -

public JsonResult GetCascadingContacts(int? modelId)
{
      var contacts = _contact.GetListQueryable();

      if (contacts != null)
      {
            contacts = contacts.Where(c => c.ModelId == modelId);
      }

      return Json(contacts.Select(c => new {ContactName = c.FirstName + " " + c.LastName, c.ContactId}));
}


Я считаю, что проблема, вероятно, в шаблоне редактора, но опять же, я не у меня действительно есть идея.

То, что я пробовал
Проверено в консоли веб-браузера на наличие ошибок, не найдено
Проверено на вывод ошибок в Visual Studio, не найдено
Я также удостоверился, что значение modelId фактически передается из моего filterContacts метода в мой контроллер, который был. Также проверяется, проверял ли метод запроса «Контакты» фактические контакты на основе modelId, которым он был.

ОБНОВЛЕНИЕ
Похоже на количество строк, которые я получаю в выпадающий список соответствует количеству контактов, которые я получаю по запросу.

ОБНОВЛЕНИЕ
Если я добавлю JsonRequestBehavior.AllowGet, который требуется для демонстрации, чтобы сделать мой ответный рейтинг return Json(contacts.Select(c => new {ContactName = c.FirstName + " " + c.LastName, c.ContactId}), JsonRequestBehavior.AllowGet); то я получаю ошибку
Property 'JsonResult.SerializerSettings' must be an instance of type 'Newtonsoft.Json.JsonSerializerSettings'.

Ответы [ 2 ]

0 голосов
/ 07 марта 2020

Проблема заключалась в том, что вместо возврата ContactName и ContactId, Json, который возвращал Кендо, было contactName и contactId. Я понял это, используя вкладку сети в инструментах разработчика браузера и увидев возвращенные данные. Вот исправленная и рабочая версия:

@model object

@(Html.Kendo().DropDownListFor(m => m)
    .DataTextField("contactName")
    .DataValueField("contactId")
    .DataSource(source =>
    {
        source.Read(read =>
        {
            read.Action("GetCascadingContacts", "ControllerName")
                .Data("filterContacts");
        })
            .ServerFiltering(true);
    })
    .Enable(false)
    .AutoBind(false)
    .CascadeFrom("ModelId"))
0 голосов
/ 06 марта 2020

Эта структура работала для меня, когда я пробовал нечто подобное в моем проекте:

Изменение:

columns.Bound(p => p.ContactId)
            .EditorTemplateName("ContactCascadingDropdown")
            .ClientTemplate("#:ContactName#");

на:

columns.ForeignKey(p => p.ContactId, Model.Contacts, "ContactId", "ContactName")
             .EditorTemplateName("ContactCascadingDropdown")
             .Title("Contact")

Что происходит выше?

  • Используем внешний ключ к шаблону
  • Определяем какое значение столбца будет p -> p.ContactId
  • Передаем список контактов информация, используя идентификатор и значение списка (в данном случае ContactId и ContactName)

Мой EditorTemplate выглядит примерно так:

@model int

@(Html.Kendo().DropDownListFor(m => m)
    .AutoBind(true)
    .DataTextField("ContactName")
    .DataValueField("ContactId")
    .DataSource(source =>
    {
        source.Read(read => read.Action("GetCascadingContacts", "ControllerName")
            .Data("filterContacts")).ServerFiltering(true);
    })
    .CascadeFrom("ModelId")

    // If this value could be a nullable you will also need the following
    .ValuePrimitive(true)
)

Возвращение Ваш метод контроллера должен быть:

return Json(contacts.Select(c => new {ContactName = c.FirstName + " " + c.LastName, c.ContactId}), JsonRequestBehavior.Allowget);
...