2012-02-06 63 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