2013-02-14 96 views
1

我認爲這個用戶提出了我所問的同一個問題,但推動他的問題的原因是不同的,所以他接受了不同的解決方案。我需要做什麼,他最初問:自動取消jqGrid請求

Automatically cancelling jqgrid request

我的jqGrid有一個搜索工具欄(即出現下面的列標題,但上面的數據輸入字段)。大多數列都有下拉列表(stype = select),列出了該列的可用過濾選項,頂部有一個「全部」選項。用填充我的jqGrid的JSON數據響應的服務器端代碼非常複雜,因此速度有點慢,特別是當過濾條件沒有太多的時候。這意味着如果用戶選擇「全部」,則可能需要幾秒鐘才能顯示結果。這本身就很好,但如果用戶在響應返回之前做出另一個篩選器選擇,則網格不會取消現有的請求,也不會提交新的請求,因此在之後的某個點處,用戶進行第二次選擇,網格會更新以顯示第一個選擇的響應。此外,網格自動更新,當你選擇過濾器時,爲了讓它顯示你想要的數據,你必須改變你的選擇,等待它加載,然後再改回來。

這裏是我試過到目前爲止:

$(document).ready(setupGrid); 

var currentGridRequest; 

function setupGrid() { 
    var grid = $("#grid").jqGrid({ 
     ... 
     loadError: function(xhr, status, error) { 
      currentGridRequest = undefined; 
     }, 
     loadComplete: function(data) { 
      currentGridRequest = undefined; 
     }, 
     loadBeforeSend: function(xhr, settings) { 
      if (currentGridRequest !== undefined) { 
       currentGridRequest.abort(); 
      } 
      currentGridRequest = xhr; 
     } 
    }); 
} 

我的問題是,loadBeforeSend事件實際上並沒有火是否已存在飛行中的請求。我從事件文檔頁面(http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events)嘗試了其他事件:beforeRequest和jqGridToolbarBeforeSearch都顯示相同的行爲。

如何取消正在進行的請求並根據用戶最近的選擇繼續進行搜索?這是jqGrid中的錯誤嗎?我最初在版本4.2上遇到過這個問題;我剛剛升級到4.4.4,這種行爲沒有任何變化。

看着jqGrid代碼,我看到的行爲似乎是不可避免的,無需更改jqGrid代碼本身。 jqGrid在每個請求的開始處設置一個標誌(ts.grid.hDiv.loading),並在最後清除它;當設置此標誌時,不會提交新的過濾標準,也不會觸發事件。

我也考慮過修改我的JSON響應,以便它包含請求標準,然後編寫一些JS代碼來將響應與當前條件選擇進行比較。如果它們不匹配,我會忽略該響應並且不將其呈現給網格。由於jqGrid甚至不提交第二組標準,該選項不在表格中(即使我能解決這個問題,我目前的方法似乎也是可取的)。

回答

1

我找到了一種方法來做我想做的事。我在幾個地方使用了jqGrid(在少數情況下在同一頁面上包含多個網格),所以我將它分解成一個函數,我可以從任何地方調用它,並且包含它自己的作用域以管理是否存在當前請求;只需將它傳遞給一個網格,它將附加所有必要的事件處理程序。請注意,這將覆蓋您可能爲相關事件定義的任何現有處理程序。

function applyJqgridHandlers(grid) { 
    (function(self, undefined) { 
     var currentRequest; 
     function abortCurrentRequestIfAny() { 
      if (currentRequest !== undefined) { 
       currentRequest.abort(); 
      } 
     } 
     self.clearCurrentRequest = function() { 
      abortCurrentRequestIfAny(); 
      currentRequest = undefined; 
     }; 
     self.setCurrentRequest = function(xhr) { 
      abortCurrentRequestIfAny(); 
      currentRequest = xhr; 
     }; 
    })(grid.currentRequestHolder = {}); 

    grid.currentRequestHolder.clearCurrentRequest(); 
    grid.jqGrid('setGridParam', { 
     loadError: function(xhr, status, error) { 
      grid.currentRequestHolder.clearCurrentRequest(); 
     }, 
     loadBeforeSend: function(xhr, settings) { 
      grid.currentRequestHolder.setCurrentRequest(xhr); 
     }, 
     loadComplete: function(data) { 
      grid.currentRequestHolder.clearCurrentRequest(); 
     } 
    }); 
    grid.bind('jqGridToolbarBeforeSearch', function() { 
     grid.currentRequestHolder.clearCurrentRequest(); 
     this.grid.hDiv.loading = false; 
    }); 
}; 

然後我簡單地從setupGrid()的末尾添加一個對這個函數的調用。

此代碼顯式清除ts.grid.hDiv。加載標誌,這是不公佈的jqGrid API的一部分,所以我認爲這個解決方案相當脆弱;不能保證它會繼續爲未來版本的jqGrid工作。如果任何人有任何關於解決這個問題的更好(不那麼脆弱)方法的建議,我全都聽過。 :)

0

@JakeRobb謝謝你的想法!我冒昧地創建了一個可以普遍使用的函數,而不禁用原始jqGrid的任何功能。

測試上的jqGrid 5.2.1版

jqGrid的快速搜索

a.k.a自動如果一個新的過濾器由使用者施加取消舊的請求。

/** 
 
* Add the ability to rapidly search using the jqGrid Toolbar 
 
* 
 
* @param jqGridInstance string|object 
 
* 
 
* @author Kiril Reznik 
 
*/ 
 
var jqGridRapidSearch = function(jqGridInstance) { 
 
    var currentRequest = null, 
 
     abortRequest = function() { 
 
      if (currentRequest !== null) { 
 
       currentRequest.abort(); 
 
      } 
 
     }, 
 
     setRequest = function(xhr) { 
 
      abortRequest(); 
 
      currentRequest = xhr; 
 
     }, 
 
     clearRequest = function() { 
 
      abortRequest(); 
 
      currentRequest = null; 
 
     }, 
 
     $jqGrid = null; 
 
    if ($.type(jqGridInstance) === 'string') { 
 
     $jqGrid = $(jqGridInstance); 
 
    } else if ($.type(jqGridInstance) === 'object' && $.type(jqGridInstance.jquery) === 'string') { 
 
     $jqGrid = jqGridInstance; 
 
    } else { 
 
     throw 'jqGridRapidSearch requires a valid jqGrid instance parameter: Grid ID string or jQuery object.'; 
 
    } 
 
    $jqGrid.on('jqGridLoadBeforeSend', function(e, xhr, settings) { 
 
     setRequest(xhr); 
 
    }); 
 
    $jqGrid.on('jqGridLoadComplete', function(e, data) { 
 
     clearRequest(); 
 
    }); 
 
    $jqGrid.on('jqGridLoadError', function(e, xhr, status, error) { 
 
     clearRequest(); 
 
    }); 
 
    $jqGrid.on('jqGridToolbarBeforeSearch', function(e) { 
 
     clearRequest(); 
 
    }); 
 
};