2011-09-08 97 views
3

我正在使用jqGrid,並希望能夠使用其內置的編輯功能,使Ajax調用添加/編輯/刪除。我們的API使用REST風格的動詞和URL像這樣:使用jqGrid的RESTful url進行內聯編輯?

verb  url    action 
-------------------------------------------------------------- 
GET  /api/widgets  get all widgets (to populate grid) 
POST  /api/widgets  create new widget 
PUT  /api/widgets/1 update widget 1 
DELETE /api/widgets/1 delete widget 1 

是否有可能使用這些限制內置AJAX處理,或做我必須使用本地數據(如概述here & here)和管理阿賈克斯稱自己?如果可能的話,我在網格上設置了哪些屬性?

ajaxRowOptions看起來很有希望,但documentation是有點薄如何使用它。)

+0

要使用哪種編輯模式:內聯編輯,表單編輯,「動作」格式化程序或某些組合(例如添加/刪除表單編輯和內聯編輯編輯)? – Oleg

+0

理想情況下,創建新窗口小部件的表單編輯,編輯它們的內聯編輯以及刪除它們的動作圖標。 :)第二種選擇可能是所有三種「選擇一行然後單擊一個按鈕」模式。 – sprugman

+0

所有這一切都是可能的,但只有不同的代碼。我會盡量在下次(可能明天)寫下答案。今天,我花了太多時間用於jqGrid,不得不返回到我的主要業務。 :-) – Oleg

回答

10

POST在添加表格的使用默認情況下。

定製jqGrid for RESTfull後端的主要想法可以在the old answer中找到。

如果使用導航器工具欄的刪除按鈕,可以在表單編輯中使用「刪除」。看看herehere。所以,你應該使用有關以下設置:

$("#grid").jqGrid('navGrid', '#pager', 
    {edit: false, add: false, search: false}, {}, {}, 
    { // Delete parameters 
     mtype: "DELETE", 
     serializeDelData: function() { 
      return ""; // don't send and body for the HTTP DELETE 
     }, 
     onclickSubmit: function (params, postdata) { 
      params.url = '/api/widgets/' + encodeURIComponent(postdata); 
     } 
    }); 

我在上面的encodeURIComponent函數的例子中使用,以確保如果ID都會有一些特殊的字符(空格例如)如果將進行編碼,使得服務器部分自動接收到原始(解碼)的數據。可能您需要爲在發送刪除請求到服務器期間使用的$.ajax呼叫設置一些其他設置。您可以使用它ajaxDelOptions屬性。

您可以將上述設置設置爲您的默認設置。可以相對於以下

$.extend($.jgrid.del, { 
    mtype: "DELETE", 
    serializeDelData: function() { 
     return ""; // don't send and body for the HTTP DELETE 
    }, 
    onclickSubmit: function (params, postdata) { 
     params.url = '/api/widgets/' + encodeURIComponent(postdata); 
    } 
}); 

從上面可用於編輯的操作(在形式編輯的情況下)的實施例的方法onclickSubmit這樣做是爲了動態修改的URL /api/widgets/1。在很多情況下,以上形式使用onclickSubmit是不可能的,因爲需要使用不同的基址('/api/widgets')不同的網格。在這種情況下可以使用

$.extend($.jgrid.del, { 
    mtype: "DELETE", 
    serializeDelData: function() { 
     return ""; // don't send and body for the HTTP DELETE 
    }, 
    onclickSubmit: function (params, postdata) { 
     params.url += '/' + encodeURIComponent(postdata); 
    } 
}); 

隨後的navGrid的使用應符合url

$("#grid").jqGrid('navGrid', '#pager', 
    {edit: false, add: false, search: false}, {}, {}, 
    { // Delete parameters 
     url: '/api/widgets' 
    }); 

和 明確設置爲內聯用「把」編輯您可以設置以下默認jqGrid的設置:

$.extend($.jgrid.defaults, { 
    ajaxRowOptions: { contentType: "application/json", type: "PUT", async: true }, 
    serializeRowData: function (data) { 
     var propertyName, propertyValue, dataToSend = {}; 
     for (propertyName in data) { 
      if (data.hasOwnProperty(propertyName)) { 
       propertyValue = data[propertyName]; 
       if ($.isFunction(propertyValue)) { 
        dataToSend[propertyName] = propertyValue(); 
       } else { 
        dataToSend[propertyName] = propertyValue; 
       } 
      } 
     } 
     return JSON.stringify(dataToSend); 
    } 
}); 

設置contentType: "application/json"不是一般的要求,但它可能需要一些SE技術。上例中的回調函數serializeRowData以JSON形式發送數據。它不是RESTfull所必需的,但它很常見。功能JSON.stringify本地在最新的Web瀏覽器中實現,但要確保它在舊版瀏覽器中可以正常工作,則應在您的頁面上包含json2.js

serializeRowData代碼也能像

serializeRowData: function (data) { 
    return JSON.stringify(data); 
} 

很簡單,但我用上面的代碼,以便能夠使用的功能的方法editRowextraparam的內部(參見here和問題說明here)。

的REST類型的URL(如/api/widgets/1)在editRow的用法很簡單:

$(this).editRow(rowid, true, null, null, '/api/widgets/' + encodeURIComponent(rowid)); 

要使用它的形式的情況下編輯,你應該使用

grid.navGrid('#pager', {}, 
    { mtype: "PUT", url: '/api/widgets' }); 

$.extend($.jgrid.edit, { 
    ajaxEditOptions: { contentType: "application/json" }, // can be not required 
    onclickSubmit: function (params, postdata) { 
     params.url += '/' + encodeURIComponent(postdata.list_id); 
    } 
}); 

重要的是要得到idpostdata裏面的onclickSubmit和需要使用postdata.list_id而不是postdata.id,其中'list'是網格的id。爲了能夠使用不同的網格(<table>)ID可以使用新的非標準參數。例如,在下面的代碼我使用myGridId

var myEditUrlBase = '/api/widgets'; 
grid.navGrid('#pager', {}, 
    { mtype: "PUT", url: myEditUrlBase, myGridId: 'list' }, 
    { // Add options 
     url: myEditUrlBase }, 
    { // Delete options 
     url: myEditUrlBase }); 

和默認設置定義爲

$.extend($.jgrid.del, { 
    mtype: "DELETE", 
    serializeDelData: function() { 
     return ""; // don't send and body for the HTTP DELETE 
    }, 
    onclickSubmit: function (params, postdata) { 
     params.url += '/' + encodeURIComponent(postdata); 
    } 
}); 

$.extend($.jgrid.edit, { 
    ajaxEditOptions: { contentType: "application/json" }, // can be not required 
    onclickSubmit: function (params, postdata) { 
     params.url += '/' + encodeURIComponent(postdata[params.myGridId + '_id']); 
    } 
}); 

formatter:'actions'使用的情況下(見herehere)配有內聯或形式編輯(或混合),您可以使用前面所述的相同技術,但使用editOptionsdelOptions formatoptions轉發所有需要的編輯/刪除選項。

最後一個問題是使用GET作爲/api/widgets。傳統的RESTfull服務將返回所有項目的數組作爲/api/widgets上的響應。因此,您應該只使用loadonce: truejsonReader,它們使用方法而不是屬性(請參閱herehere)。

loadonce: true, 
jsonReader: { 
    repeatitems: false, 
    root: function (obj) { return obj; }, 
    page: function() { return 1; }, 
    total: function() { return 1; }, 
    records: function (obj) { return obj.length; } 
} 

您應該以某種方式包含哪些item屬性可以用作網格行的id。該頁面上的ID必須爲unique。它的數據沒有ID我會建議你使用

id: function() { return $.jgrid.randId(); } 

作爲附加jsonReader方法,因爲每默認jqGrid的當前版本的使用順序整數(「1」,「2」,「3」,.. )作爲行ID。如果在同一個頁面上至少有兩個網格,它將跟隨這些問題。

如果'GET'返回的數據大小多於100行,我建議您最好使用服務器端分頁。這意味着您將在支持服務器端排序和數據分頁的服務器部分添加一個附加的方法。我建議您閱讀the answer,我在這裏描述了爲什麼輸入數據的標準格式不是RESTfull數組項目,並且還有page,totalrecords。對於傳統的RESTful設計,新方法可能並不陌生,但本地或甚至SQL代碼中的排序和分頁數據可以顯着提高最終用戶的總體性能。如果標準jqGrid輸入參數的名稱(pagerows,sidxsord)可以使用prmNames jqGrid參數在那裏重命名。

+0

感謝您的徹底解答!在文檔中,我可以找到這樣的參數:$(「#grid」)。jqGrid('navGrid','#pager', {edit:false,add:false,search:false}, {},{}, {//刪除參數 url:'/ api/widgets' }); – sprugman

+0

我認爲這是一個已經建好的網格上的API調用,但是在http://www.trirand.com/jqgridwiki/doku.php?id=wiki:methods方法列表中看不到'navGrid' – sprugman

+0

哦,找到它了。當然在「自定義按鈕」下。 : - | – sprugman

1

還檢查了關於如何建立jqGrid的REST風格的URL的here,其中還包括相應的Spring MVC的服務器部分會怎樣看這個優秀的通用教程。

0

我設法通過實施beforeSubmitCell事件處理程序來實現它:

beforeSubmitCell: function(rowId) { 

      jQuery("#grid-HumanResource-table").jqGrid(
       'setGridParam', 
       { 
        cellurl: s.getBaseModule().config.baseAPIUrl + "humanResource/" + rowId 
       } 
      ); 
     }, 

我使用的jqGrid 4.6版本。