Kendo Grid - взять столбец из представления и объединить его с сохраненными параметрами сетки - PullRequest
0 голосов
/ 15 октября 2018

Мы используем Kendo Grid для MVC .NET.В настоящее время мы загружаем сетки, используя синтаксис бритвы в пользовательском интерфейсе, и вызываем действия чтения с использованием контроллеров MVC.

Проблема в том, что мы позволяем конечным пользователям сохранять «Профили» на основе того, как они сортируют, фильтруют и упорядочивают данные и столбцы своих сеток на каждой странице.Я пишу интерфейсный код JavaScript, который обрабатывает несколько сценариев, с которыми мы столкнулись, как описано ниже.

  1. Что если мы изменим / изменим HTML в режиме реального времени, а затем они загрузят профиль?В этот момент код неверен.

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

Проблема заключается в том, что если я возьму столбец, который недавно добавлен в динамическом представлении (но отсутствует в сохраненном состоянии в базе данных)) и добавить его в массив options.columns, он не рендерится при перезагрузке сетки.Разве это не правильный способ справиться с этим, или что мне нужно сделать, чтобы это работало должным образом?

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

 function loadDefaultSettings() {
    let grid = $("#" + targetGrid);
    let gridData = grid.data("kendoGrid");

    $.ajax({
        type: "GET",
        url: window.baseUrl + "/UserProfile/GetDefaultSettings",
        data: {
            pageId: userPageId
        }
    }).done(function (result) {

        if (result !== undefined && result !== null) {
            if (result.Name !== 'Standard') {
                let state = JSON.parse(result.ConfigurationJson);
                let options = gridData.options;
                //let toolBar = $("#controlGrid .k-grid-toolbar").html();
                let toolBar = grid.find(".k-grid-toolbar").html();


                /*
                *   Instead of just loading the profile stae that was tored over the current default loaded grid,
                *   we will first scoop all columns of default grid, and place into temp arrays as well as a rray for 
                *   a lookup data structure of only the default grid column titles.
                *   We will use both arrays later to determine if a new column exist (missing from profile state columns stored) and if so append it
                *   to the grid AFTER the profile settings are laoded.
                */
                let tempDefaultColumnsMissingToAdd = []; //tempArray to hold any Full Column data objects that are not found in profile state saved
                let tempDefaultColumnTitlesLookup = []; //Only the titles of the newly found columns, used to look up 
                let tempStateColumnTitles = [];
                let tempStateColumnsToRemove = [];
                let defaultGridMetaProperties = []; //object with properties such as Menu [allow hiding (boolean)], Template

                //lets now get all column titles of default grid that is untouched. May contain newly added code to the kedno grid view at runtime, also get menu (if able to hide or not [bollean], and template).
                //Menu and Template properties ONLY exist if defined and used, if not it is non existent. So most will be this way hence why we do the object
                //proprty method testing
                for (let c = 0; c < gridData.columns.length; c++) {
                    let columnObj = {
                        title: gridData.columns[c].title,
                        menu: gridData.columns[c].hasOwnProperty("menu") ? gridData.columns[c].menu : null, //check if this column definition contains a menu property. :Remember does not exist if not set.
                        template: gridData.columns[c].hasOwnProperty("template") ? gridData.columns[c].template : null //check if column definition contains a template property 
                    };
                    defaultGridMetaProperties.push(columnObj); //NOTE: This index is trackable since in same array order as titles is placed and built
                    tempDefaultColumnTitlesLookup.push(gridData.columns[c].field);
                }

                //now lets get all column titles from state
                for (let s = 0; s < state.columns.length; s++) {
                    tempStateColumnTitles.push(state.columns[s].field); //we will know how to get back to this item index in the object columns array, due to index position saved.
                }

                //*** GET NEWLY ADDED COLUMNS MISSING FROM PROFILE ***//
                //now we have our column titles form default initial loaded grid.
                //lets see if the columns stored in profile are missing any
                for (let tdc = 0; tdc < tempDefaultColumnTitlesLookup.length; tdc++) {
                    if(!tempStateColumnTitles.includes(tempDefaultColumnTitlesLookup[tdc])) {
                        //the column does not exist in the saved data structure state in profile
                        //add it to temp array so we can append later AFTER we set the profile to the grid.
                        tempDefaultColumnsMissingToAdd.push(gridData.options.columns[tdc]); //since array goes in order for titles in same indec as objects, we can say this title is in same index position of array as its column object
                    }
                }

                //*** GETTING ANY COLUMNS THAT MAY BE SAVED IN PROFILE THAT NO LONGER ARE IN CODE ***//
                //now lets see if ANY columns have been removed from the view grid.
                //If so we dont want them to STILL load if the profile contains them.
                for (let rsc = 0; rsc < tempStateColumnTitles.length; rsc++) {
                    if (!contains(tempDefaultColumnTitlesLookup, tempStateColumnTitles[rsc])) {
                        tempStateColumnsToRemove.push(state.columns[rsc]); //so we found aold column saved in a profile, but is no longer in live code in grid view. Remove it before setting options.
                    }
                }

                //before we set the profile to saved profile, lets see if we have old columns we need removed from saved profile data structure
                if (tempStateColumnsToRemove.length > 0) {
                    let removingIndexes = [];
                    for (let z = 0; z < state.columns.length; z++) {
                        for (let a = 0; a < tempStateColumnsToRemove.length; a++) {
                            //when we find it, remove it.
                            // console.log(tempStateColumnsToRemove[a]);
                            if (state.columns[z] === tempStateColumnsToRemove[a]) {
                                //foudn it and remove
                                removingIndexes.push(z);
                            }
                        }
                    }

                    if (removingIndexes.length > 0) {
                        var tempArryTOHandleReadjustingSize = [];
                        for (let d = 0; d < state.columns.length; d++) {
                            //state.columns.splice(1, d);
                            if (!contains(removingIndexes, d))//is this indexed item does not conatin it index value in list of indexes to remove, then add to preserved array to keep.
                            {
                                //it is not found in list to remove so add to temp array.
                                tempArryTOHandleReadjustingSize.push(state.columns[d]);
                            }
                        }

                        //now overwrite state.columns object with new arrays we are to keep, hence ridding items we needed to remove.
                        options.columns = tempArryTOHandleReadjustingSize;
                    }
                }


                if (tempDefaultColumnsMissingToAdd.length > 0) {
                    //we found new ones so now append to options.columns the already set profile
                    for (let nc = 0; nc < tempDefaultColumnsMissingToAdd.length; nc++) {
                        state.columns.push(tempDefaultColumnsMissingToAdd[nc]); //are new found column in the default grid has been PUSHED onto the profile columns stack.
                    }
                }

                //now lets loop through and update any templates and Menu properties that may have changed on default production runtime view,
                //but is not stored in the profile datastructure.
                for (let meta = 0; meta < gridData.options.length; meta++) {
                    //if and ONLY if proprty found do we update it. No sense in checking all.
                    let columnContext = gridData.options.columns[meta];

                    if (columnContext.hasOwnProperty("template") || columnContext.hasOwnProperty("menu")) {
                        //now find that same col definition in our newly built profile of columns
                        for (let z = 0; z < state.columns.length; z++) {
                            /* This part is little strange unless you understand advanced Javascript theory. You can always assign a new property
                            * to a object of a property that does not exist. It will just add it. But if you however, try to reference a proeprty
                            * that does not exist you will get a undefined error. Also once you reference a proeprty, it is part of the object.
                            * That is why the menu property can be set and then determined true or false. If there is a value, we set it,
                            * and if not we set the defsult value. The template proeprty however, is tricky. If it never had atemplate proeprty,
                            *we cannot assign it something like null or EMPTY, as kendo will then see a template exist and try to rener it.
                            *hence why the second check is made to MAKE SURE a template item already existed before looking to update.
                            */
                            if (state.columns[z].field === columnContext.field) {
                                //state.columns[z].menu = defaultGridMetaProperties[meta].hasOwnProperty("menu") ? defaultGridMetaProperties[meta].menu : false; //TRUE IS DEFAULT TO ALLOW SHOWING UP IN (Hide Menu Tool Option)
                                //if (columnContext.hasOwnProperty("template")) {
                                    //state.columns[z].template = defaultGridMetaProperties[meta].template;
                                    state.columns[z]= columnContext;
                                //}
                                //break; //break out do not conitnue wasting processing
                            }
                        }
                    }
                }

                //now we have our newly added columns, if any exist lets build profile, then add them in by appending to the array stack.
                console.log(state.columns);

                options.dataSource.fields = state.columns;
                console.log(options.dataSource.fields);
                options.dataSource.page = state.page;
                options.dataSource.pageSize = state.pageSize;
                options.dataSource.sort = state.sort;
                options.dataSource.filter = state.filter;

                gridData.setOptions(options);
                    //.empty()
                    //.kendoGrid(options);

                //$("#controlGrid .k-grid-toolbar").html(toolBar);
                //$("#controlGrid .k-grid-toolbar").addClass("k-grid-top");
                grid
                    .find(".k-grid-toolbar")
                    .html(toolBar)
                    .addClass("k-grid-top");

                gridData = grid.data("kendoGrid");


                $dlgSelectProfile.modal("hide");

                $("label[name='selLblProfileName']").html("Selected Profile :" + result.Name);
                $updateProfile.data("profileId", result.Id);
                $updateProfile.data("name", result.Name);
                $updateProfile.data("description", result.Description);
                $updateProfile.data("isDefault", result.IsDefault);
                $profileId.val(result.Id);

                if (toolBar.indexOf('actionList') >= 0) {
                    $("#actionList").kendoDropDownList({
                        dataTextField: "text",
                        dataValueField: "value",
                        index: 0
                    });
                }

                if (toolBar.indexOf('dueCriteriaMenuControlChange') >= 0) {
                    $("#dueCriteriaMenuControlChange").kendoDropDownList({
                        dataTextField: "text",
                        dataValueField: "value",
                        index: 0
                    });
                }


            }
            else {
                $("label[name='selLblProfileName']").html("Selected Profile :" + result.Name);
            }
        }

        if ($("#" + targetGrid).attr("data-render-client-template") == "true") {
            let $targetHeaderemplate = $("#" + targetGrid + " .k-grid-header-wrap [data-index=0]");
            let $elementTemplate = $("#" + targetGrid + " .k-filter-row th:first-child");

            $targetHeaderemplate.html("Select All");
            $elementTemplate.html("<input type='checkbox' id='masterCheckBox' onclick='checkAll(this)'/>");
        }

        gridData.dataSource.read();


    })
        .fail(function (fail) {
            console.log(fail);
        }).always(function() {
            gridData.dataSource.read();
            });
}
...