проблема с сериализацией / десериализацией настроек сетки кендо

#javascript #json #kendo-ui #kendo-grid #telerik-grid

#javascript #json #kendo-пользовательский интерфейс #kendo-grid #telerik-grid

Вопрос:

Надеюсь, у кого-то есть решение. У нас есть пара сеток, в столбцах сетки которых есть пользовательские множественные выборки. Проблема в том, что JSON, похоже, отказывается правильно сериализовать / десериализовать их, когда выбрано более одного параметра. это работает:

 a = $("#grid").data("kendoGrid").getOptions();

$("#grid").data("kendoGrid").setOptions(a);
 

однако это нарушает:

 a = JSON.parse(JSON.stringify($("#grid").data("kendoGrid").getOptions()));

$("#grid").data("kendoGrid").setOptions(a);
 

и раздражающая часть этого — это, безусловно, сериализуемая часть уравнения, которая сбивает с толку, поэтому оказывается трудно точно определить, как это должно было выглядеть по сравнению с тем, как оно выглядит на самом деле после модификации. Сравнение строк равно. Есть предложения?

пример сломался: в столбце a есть выпадающий фильтр сетки с тремя параметрами: 1, 2, 3. Выбор более одного из них нарушает сетку при сохранении, а затем загружается. Выбор только единицы или нуля работает.

редактировать: вот инициализация сетки: обратите внимание, что DCGrid является переопределением сетки kendo, которая задает общие для всех сеток свойства, такие как размер страницы.

 @(Html.DCGrid<Order>("grid")
            .DataSource(dataSource => dataSource
                .Ajax()
                .Sort(s => { if (Request.QueryString.Keys.Count == 0) { s.Add(x => x.OrderNum).Ascending(); } })
                .Model(model => model.Id(o => o.ID))
                .PageSize(Settings.DefaultPageSize)
                .Read(read => read.Action("Read", "OrderSearch").Data("getParameters"))
            )
            .Events(e => e.ColumnReorder("onColumnReorder"))
            .Reorderable(r => r.Columns(true))
            .ColumnMenu()
            .Columns(columns =>
            {
                if (User.IsInRole("viewOrders"))
                {
                    columns.Template(@<text></text>)
                            .ClientTemplate("#= rowCommandsUndelete(data, true, false) #")
                            .HtmlAttributes(new { reorderable = "false" })
                            .Title("amp;nbsp;")
                            .Width(86);
                }
                columns.Bound(o => o.OrderNum)
                    .Width(120);
                columns.Bound(o => o.Status.Name)
                    .ClientTemplate("#= clientTemplateOrderStatus(data) #")
                    .Width(120);
                columns.Bound(o => o.Priority.ID).Title("Priority").Width(100)
                    .Filterable(f => f.Multi(true).DataSource(ds => ds.Read(r => r.Action("GetData/Priority", "Support", new { nameField = "PriorityNum" }))).ItemTemplate("kendoGridFilterData.IDTemplate"));
                columns.Bound(o => o.OrderDate)
                    .Width(120);
                columns.Bound(o => o.DueDate)
                    .ClientTemplate("#= clientTemplateDueDate(data) #")
                    .Width(140);
                columns.Bound(o => o.Product.ID)
                    .ClientTemplate("#=ellipseDiv(data.Product.ShortName)#")
                    .Title("Product")
                    .Filterable(f => f.Multi(true).DataSource(ds => ds.Read(r => r.Action("GetData/Product", "Support", new { idField = "ID", nameField = "ShortName" }))).ItemTemplate("kendoGridFilterData.IDTemplate"))
                    .Width(200);
                columns.Bound(o => o.DispatchConfirmNum)
                    .Width(140);
                    .ClientTemplate(CustomGridHelperExtensions.EditTemplate("Origin", "Name")   " #if(drillToValue(data, 'Origin.H2S')) {# <span class='label label-danger margin-left-right-5px'>H2S</span> #}#")
                    .Width(250);
                columns.Bound(o => o.OriginTank.TankNum)
                    .ClientTemplate("<a href='/OriginTanks?OriginId=#=data.OriginID#'>#=ellipseDiv(data.OriginTank.TankNum)#</a>")
                    .Width(100);
                columns.Bound(o => o.OriginBOLNum)
                    .Width(130);
                columns.Bound(o => o.Destination.Name)
                    .ClientTemplate("<a href='/Destinations?id= #=data.DestinationID# '>#=ellipseDiv(data.Destination.Name)#</a>")
                    .Title("Destination")
                    .Width(250);
                columns.Bound(o => o.Carrier.Name)
                    .Title("Carrier")
                    .ClientTemplate("<a href='/carriers?id= #=data.CarrierID# '>#=ellipseDiv(data.Carrier.Name)#</a>")
                    .Width(170);
                columns.Bound(o => o.Driver.FullName)
                    .ClientTemplate("<a href='/Drivers?IDNumber=#=data.Driver.IDNumber# '>#=ellipseDiv(data.Driver.FullName)#</a>")
                    .Width(170);
            })
        )
 

и это idtemplate (javascript):

   IDTemplate: function (e) {
        return "<li><label class='k-label'><input type='checkbox' value='#:data.ID#'/>#:data.Name || data.all#</label></li>";
    }
 

Единственными параметрами, которые нас интересуют, являются сортировка, фильтрация, видимость столбца, ширина столбца и расположение столбца (для перестановки).

Комментарии:

1. можете ли вы показать инициализацию сетки со всеми столбцами?

2. да. дайте мне минуту, чтобы отредактировать вопрос

3. Проблема в том , что getOptions() возвращает много параметров , которые невозможно установить с setOptions() помощью . Я бы перефразировал ваш OQ на то, какие опции вы пытаетесь изменить, и использовал бы только это. Как вы думаете, возможно ли это?

4. я добавил вопрос, чтобы перечислить свойства, которые нас интересуют.

Ответ №1:

Вы не можете использовать функцию stringify. Например:

 let test = {
   label: 'this is label',
   calculate: function(){
     return 2   2;
  }
};

let toString = JSON.stringify(test);
console.log(toString); //returns {"label":"this is label"}
 
  • неопределенные, функции и символы не являются допустимыми значениями JSON. Если какие-либо
    такие значения встречаются во время преобразования, они либо опускаются
    (при нахождении в объекте), либо изменяются на null (при нахождении в
    массив). JSON.stringify() может возвращать неопределенное значение при передаче в «чистом» виде
    такие значения, как JSON.stringify(функция(){}) или
    JSON.stringify(не определено).

Ресурс: JSON.stringify()

Вы можете перебирать столбцы в загруженных параметрах и снова устанавливать свойства, что-то вроде этого:

 let optionsObject = JSON.parse(options);
for (let i = 0; i < optionsObject.columns.length; i  ) {
    let column = optionsObject.columns[i];
    if (column.field) {
        switch (column.field) {
            case 'field1':
                column.template = kendo.template($('#field-1-template').html());
                break;
            case 'field2':
                column.template = kendo.template($('#field-2-template').html());
                break;

            default:
                break;
        }
    }
}
 

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

 $("#grid").data("kendoGrid").setOptions(optionsObject);
 

Комментарии:

1. ваш код указал мне правильное направление для решения моей проблемы, а также помощь от гуру поддержки telerik. Спасибо. Нарушенный код устанавливал фильтр непосредственно на источник данных сетки вместо setOptions, что усложняло ситуацию. Парень, который написал это, в основном отключил способность сетки к синхронизации, переопределив события, затем установил фильтр, сортировку и столбцы отдельно. Способ, которым он устанавливал фильтры, был нарушен. Моя реализация устанавливает их с помощью .setOptions. Мне пришлось сохранить существующие функции в столбцах, чтобы наши пользовательские фильтры не были сломаны.