2012-02-06 64 views
17

在ExtJS 4.1測試版2我設法實現了無限滾動網格與遠程存儲。我基本上採取了一個現有的(全面運作)尋呼網格(與遠程存儲,篩選和排序),然後把在無限滾動適當CONFIGS:ExtJS無限滾動網格與遠程過濾器和排序

// Use a PagingGridScroller (this is interchangeable with a PagingToolbar) 
verticalScrollerType: 'paginggridscroller', 
// do not reset the scrollbar when the view refreshs 
invalidateScrollerOnRefresh: false, 
// infinite scrolling does not support selection 
disableSelection: true, 

這並不是說在這個docs任何地方(見無限滾動部分),但您需要將商店設置爲buffered: true配置。你不能store.load()加載它必須這樣做:

store.prefetch({ 
    start: 0, 
    limit: 200, 
    callback: function() { 
     store.guaranteeRange(0, 99); 
    } 
}); 

有了這一切,一切都很正常,如果我慢慢地滾動,從而使數據預取,不使用任何過濾器和Don不使用任何排序。

但是,如果我快速滾動或嘗試使無限滾動網格重新加載過濾器處於活動狀態,或者在排序過程中將其全部分開。錯誤是options is undefined

我已經花了幾個小時做一些跟蹤代碼和得出的結論是,沒有人實施遠程過濾器和遙控器滾動的無限滾動網格和谷歌搜索之外,我發現以下幾點:

過濾被打破,因爲在Ext.data.Store這種方法是通過當它從服務器需要更多數據的無限滾動叫下來:

mask: function() { 
    this.masked = true; 
    this.fireEvent('beforeload'); 
}, 

出於某種原因,這種方法觸發beforeload事件沒有Ext.data.Operation參數應該是它的一部分,如指定的here

/** 
* @private 
* Handler for store's beforeload event when configured for remote filtering 
* @param {Object} store 
* @param {Object} options 
*/ 
onBeforeLoad : function (store, options) { 

    options.params = options.params || {}; 
    this.cleanParams(options.params); 
    var params = this.buildQuery(this.getFilterData()); 
    Ext.apply(options.params, params); 

}, 

我可以從PagingScroller代碼,然後將切出的調用此mask方法:

其結果是,因爲當然「選項」是未定義在onbeforeload處理程序發生在Ext.ux.grid.FiltersFeature錯誤滾動功能非常棒。我可以像我喜歡的那樣快速滾動,並正確加載數據。 然後過濾器和排序不適用於ajax請求。

我沒有潛儘可能多的進入分選方面,但我認爲這種方法mask類似的東西,因爲那種僅僅是由operation對象所包含的另一個元素,它會導致沒有操作對象被傳遞給Ajax請求。

我在想,如果我可以弄清楚如何強制mask方法火beforeloadoperation參數(如文檔說是應該)一切都會好起來。問題是,我一直無法弄清楚如何做到這一點。有什麼建議麼?

如果有人會告訴我我錯了,而且人們實際上已經做出了這個工作,我會受到鼓舞,但是用來解決這個問題的任何重寫的片段或鏈接都將非常感激。

我也嘗試降級到4.0.7和4.0.2a,我得到了相同的結果,所以它不僅僅是一個測試版問題。

更新 - 12年2月7日:

這似乎是它實際上可能是Ext.ux.grid.FilterFeature問題不是一個無限滾動的問題。如果我刪除了FilterFeature配置,則完全無限滾動效果很好,並且在按列排序時會將排序參數傳遞給我的後端。我將開始研究FilterFeature結束的事情。

回答

14

SUCCESS!我有無限的滾動工作與遠程過濾器和遠程排序(這是在4.1測試版2,但因爲我在4.02a和4.0.7獲得相同的錯誤,我想它可以解決這些)。基本上,我只需在我的代碼中添加一些覆蓋。

我還沒有在其他瀏覽器中進行測試,但我已經在FF中進行了測試。下面是我用的是替代:

Ext.override(Ext.data.Store, { 

    // Handle prefetch when all the data is there and add purging 
    prefetchPage: function(page, options, forceLoad) { 

     var me = this, 
      pageSize = me.pageSize || 25, 
      start = (page - 1) * me.pageSize, 
      end = start + pageSize; 

     // A good time to remove records greater than cache 
     me.purgeRecords(); 

     // No more data to prefetch 
     if (me.getCount() === me.getTotalCount() && !forceLoad) { 
      return; 
     } 

     // Currently not requesting this page and range isn't already satisified 
     if (Ext.Array.indexOf(me.pagesRequested, page) === -1 && !me.rangeSatisfied(start, end)) { 
      me.pagesRequested.push(page); 

      // Copy options into a new object so as not to mutate passed in objects 
      options = Ext.apply({ 
       page  : page, 
       start : start, 
       limit : pageSize, 
       callback : me.onWaitForGuarantee, 
       scope : me 
      }, options); 
      me.prefetch(options); 
     } 
    }, 

    // Fixes too big guaranteedEnd and forces load even if all data is there 
    doSort: function() { 
     var me = this; 
     if (me.buffered) { 
      me.prefetchData.clear(); 
      me.prefetchPage(1, { 
       callback: function(records, operation, success) { 
        if (success) { 
         guaranteeRange = records.length < 100 ? records.length : 100 
         me.guaranteedStart = 0; 
         me.guaranteedEnd = 99; // should be more dynamic 
         me.loadRecords(Ext.Array.slice(records, 0, guaranteeRange)); 
         me.unmask(); 
        } 
       } 
      }, true); 
      me.mask(); 
     } 
    } 
}); 

Ext.override(Ext.ux.grid.FiltersFeature, { 

    onBeforeLoad: Ext.emptyFn, 

    // Appends the filter params, fixes too big guaranteedEnd and forces load even if all data is there 
    reload: function() { 
     var me = this, 
      grid = me.getGridPanel(), 
      filters = grid.filters.getFilterData(), 
      store = me.view.getStore(), 
      proxy = store.getProxy(); 

     store.prefetchData.clear(); 
     proxy.extraParams = this.buildQuery(filters); 
     store.prefetchPage(1, { 
      callback: function(records, operation, success) { 
       if (success) { 
         guaranteeRange = records.length < 100 ? records.length : 100; 
         store.guaranteedStart = 0; 
         store.guaranteedEnd = 99; // should be more dynamic 
         store.loadRecords(Ext.Array.slice(records, 0, guaranteeRange)); 
        store.unmask(); 
       } 
      } 
     }, true); 
     store.mask(); 
    } 
}); 

我的存儲器配置,像這樣:

// the paged store of account data 
var store = Ext.create('Ext.data.Store', { 
    model: 'Account', 
    remoteSort: true, 
    buffered: true, 
    proxy: { 
     type: 'ajax', 
     url: '../list?name=accounts', //<-- supports remote filter and remote sort 
     simpleSortMode: true, 
     reader: { 
      type: 'json', 
      root: 'rows', 
      totalProperty: 'total' 
     } 
    }, 
    pageSize: 200 
}); 

網格是:

// the infinite scroll grid with filters 
var grid = Ext.create('Ext.grid.Panel', { 
    store: store, 
    viewConfig: { 
     trackOver: false, 
     singleSelect: true, 
    }, 
    features: [{ 
     ftype: 'filters', 
     updateBuffer: 1000 // trigger load after a 1 second timer 
    }], 
    verticalScrollerType: 'paginggridscroller', 
    invalidateScrollerOnRefresh: false,   
    // grid columns 
    columns: [columns...], 
}); 

而且初始負載必須這樣做(不只是store.load()):

store.prefetch({ 
    start: 0, 
    limit: 200, 
    callback: function() { 
     store.guaranteeRange(0, 99); 
    } 
});  
4

你的回答提供了正確的方向,我修改您的代碼

store.loadRecords(Ext.Array.slice(records, 0, count)); 

store.loadRecords(Ext.Array.slice(records, 0, records.length)); 

這個固定以前的過濾器返回空結果的問題。插入此更改後,它正常工作。

+1

不錯的地方。我明白你在說什麼,我認爲:當商店過濾到低於保證範圍時,保證範圍將保持在該數量,並且不會加載更多。雖然解決方案的問題是保證範圍將與商店的大小相同,並且不會因爲預取而導致結果,這意味着當網格正常滾動時,一旦您通過行200或任何頁面大小是。我在覆蓋中添加了一個解決方案,但它不是很動態。我設置爲static 100的guaranteeRange變量,因爲這是我的。 – Geronimo 2012-02-26 02:48:26