2012-02-06 10 views
17

ExtJS 4.1 beta 2では、リモートストアで無限のスクロールグリッドを実装することができました。私は基本的に(フィルタリングやソート、遠隔店で)既存の(完全に動作)ページンググリッドを取った後、無限スクロールのための適切なコンフィグに入れる:それはdocsでこのどこにも言いません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, 

(参照無限スクロールセクション)、店舗をbuffered: trueに設定する必要があります。すべては私がゆっくりスクロールするので、データをプリフェッチすることを可能にする場合は、任意のフィルタを使用し、ドンしていない素晴らしい作品、すべてのことで

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

:そして、あなたはそれがこのように行われる必要がありstore.load()にロードすることはできませんソートを使用しないでください。

しかし、私が高速にスクロールしたり、フィルタをアクティブにしたり、ソートしている間に無限のスクロールグリッドを再作成しようとすると、すべてが壊れてしまいます。エラーはoptions is undefinedです。

私は時間コードにいくつかのトレースを行うと、グーグルのカップルを費やしてきたし、別に誰がリモートのフィルタおよびリモートスクロールで無限スクロールグリッドを実装していないと結論づけから、私は次のことを発見した:

それは、サーバからのより多くのデータを必要とするとき、フィルタリングが無限スクロールによって呼び出されるExt.data.Storeであるため、この方法を打破されています

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

何らかの理由で、この方法はなしbeforeloadイベントを発生させますパラメータは、指定されたhereの一部であると考えられます。

その結果、エラーが原因で、もちろんExt.ux.grid.FiltersFeatureonbeforeloadハンドラで発生した「オプション」未定義です:

/** 
* @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メソッドの呼び出しを切り出し、その後することができますスクロール機能は素晴らしいです。私は好きなだけ速くスクロールすることができ、データを適切に読み込みます。 しかし、の場合、フィルターとソートはajax要求に適用されません。

私は、ソート側面に同じくらい潜っていないが、ソートは単純operationオブジェクトに含まれる他の要素であるので、私はそれをこのmask方法と類似した何かを考え、それがアヤックスに渡される何操作対象を生じません要求。

私は(ドキュメントは、それがすることになっていると言うように)私はちょうどすべてがうまくなりますoperationパラメータでbeforeloadを発射するmask方法を強制する方法を見つけ出すことができればと考えています。問題は、私はそれを行う方法を理解することができませんでした。助言がありますか?

私が間違っていると言って、人々が実際にこの仕事をしたとすれば、私はインスパイアされますが、この問題やリンクを処理するために使用したオーバーライドのスニペットは非常に高く評価されます。

また、4.0.7と4.0.2aにダウングレードしてみましたが、同じ結果が得られました。それだけでベータの問題ではありません。

アップデート - 2月7日12:

それは実際にExt.ux.grid.FilterFeature問題ない無限スクロールする問題がある可能性がありますようにこれがそうです。私がFilterFeatureの設定を完全に無限にスクロールしてもうまくいき、列で並べ替えると、ソートのパラメータがバックエンドに渡されます。私は物事のFilterFeatureの終わりを調べ始めるでしょう。

答えて

14

成功!私はリモートフィルタとリモートソートを使って無限のスクロールを行っています(これは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を超えるか、ページサイズはオーバーライドにソリューションを追加しましたが、これはあまり動的ではありません。私が静的な100に設定したguaranteeRange変数は、それが私のものだからです。 – Geronimo

関連する問題