Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
910 views
in Technique[技术] by (71.8m points)

jquery - When using jqgrid, is there anyway to have recreateForm: true but also cache dataUrl?

I have the following columns using jqGrid (simplified)

  { name: "PMOPerson", index: "PMOPerson", width: 250, editable: true, edittype: "select", editoptions: { dataUrl: "/Person/GetSelectData" }, editrules: { required: false} },

  { name: "HeadDisplayName", index: "HeadDisplayName", width: 150, editable: false },

when i go to edit a row by bringing up the edit dialog, it take 10 seconds for the PMOPerson dropdown to be populated. This is the case even after i have already loaded it once before and i assume that is because i have recreateForm: true below

  addButton({
    caption: "",
    title: "Edit Selected Team",
    buttonicon: 'ui-icon-pencil',
    onClickButton: function () {
        var id = $("#grid").getGridParam("selrow");
        if (id) {

            jQuery("#grid").jqGrid('editGridRow', id,
                    { url: '/OrganisationalUnit/Update', afterSubmit: function (response, postdata) {
                        var responseJson = $.parseJSON(response.responseText);
                        return HandleJqGridResponse(responseJson);
                    },
                        height: 380, width: "auto", recreateForm: true, closeAfterEdit: true,
                        closeOnEscape: true, reloadAfterSubmit: true
                    });
        }
    },
    position: "second"
});

I am trying to figure out if there is a way I can have both recreateform: true but still also cache the list of items in dataUrl to avoid going back to the server each time I edit a row.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I answered on very close questions here and here. In other words you can either use caching options of HTTP header or to use editoptions.value instead of editoptions.dataUrl.

I described in the answer and this two previous one (this and this) how one can set editoptions.value dynamically inside of beforeProcessing callback. One need extend the responses from the server used to fill the grid with additional information (with the data like the data returned from editoptions.dataUrl). In my opinion it implements the best compromis between caching of editoptions.dataUrl data and refreshing of the data by reloading of the grid. One can still hold cached editoptions.dataUrl data on the server side.

Alternatively one can use more simple way where one makes manual Ajax request to editoptions.dataUrl once after creating of the grid and one can set editoptions.value inside of success (done) callback of the Ajax request. The code will be about the following

// create grid
$("#grid").jqGrid({
    colModel: [
        { name: "PMOPerson" },
        ...
    ],
    ...
});

// make separate asynchronous Ajax request to the server and set 
//  edittype: "select", editoptions: { value: ... }
setSelectOptionValues("/Person/GetSelectData", $("#grid"), "PMOPerson");

The code of setSelectOptionValues depends on the format of JSON data which you use to communicate with URL like "/Person/GetSelectData". For example if the server returns just array of strings wich should be the text and the value of options of the <select> then the could could be the following

var setSelectOptionValues = function (getJsonUrl, myGrid, colModelColumnName) {
    $.getJSON(
        getJsonUrl,
        function (data) {
            var i, selectedOptions = '', datai, dn, colModelColumn;

            for (i = 0; i < data.length; i += 1) {
                if (i > 0) {
                    selectedOptions += ';';
                }
                else {
                    selectedOptions = "";
                }
                datai = data[i];

                if (typeof datai === 'string') {
                    selectedOptions += datai;
                    selectedOptions += ':';
                    selectedOptions += datai;
                }
            }
            myGrid.jqGrid("setColProp", colModelColumnName, {
                edittype: "select",
                editoptions: { value: selectedOptions }
            });
        }
    );
};

The setting of editoptions.value will be done asynchronously inside of setSelectOptionValues. So it can be that the grid will be filled before the editoptions.value will be set. On the other side editoptions.value will be used only during editing. The response time from "/Person/GetSelectData" will be typically quick enough and the value editoptions.value will be set before the user start editing. If you want be absolutely sure you can still hold editoptions.dataUrl. In the case editoptions.dataUrl will be used only if the user quickly as the server with responding on "/Person/GetSelectData". You can change explicit call of

setSelectOptionValues("/Person/GetSelectData", $("#grid"), "PMOPerson");

with getting of colModel using getGridParam, the loop through all colModel items and calling of setSelectOptionValues for all items which has editoptions.dataUrl.

The main restriction of the last approach: you can't use formatter: "select" (just edittype: "select" only). If you fill grid data with ids and editoptions.value or formatoptions.value provides the mapping of ids to the texts then I would recommend you to use the first approach with beforeProcessing callback.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...