2012-02-06 12 views
17

W ExtJS 4.1 beta 2 udało mi się zaimplementować nieskończoną siatkę przewijania ze zdalnym sklepem. I w zasadzie wziął istniejącego (w pełni sprawny) siatkę stronicowania (z odległego sklepu, filtrowanie i sortowanie), a następnie umieścić w odpowiednich configs dla nieskończonego przewijania:ExtJS Infinite Scroll Grid ze zdalnymi filtrami i sortowaniem

// 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, 

nie mówi nigdzie w docs (patrz Sekcja Nieskończone przewijanie), ale musisz ustawić swój sklep na konfigurację buffered: true. I nie można załadować z store.load() to trzeba zrobić tak:

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

Z wszystkich, że wszystko działa świetnie, gdybym przewijać powoli, a tym samym umożliwić danych do pobierania wstępnego, nie stosować żadnych filtrów i Don użyj dowolnego sortowania.

Jednakże, jeśli przewijam szybko lub próbuję ponownie załadować siatkę nieskończonego przewijania z aktywnym filtrem lub podczas sortowania, wszystko się rozpada. Błąd to options is undefined.

spędziłem kilka godzin jakiejś śledzenie w kodzie i googlowania i oprócz stwierdzenia, że ​​nikt nie wdrożył nieskończoną przewijania siatkę z odległych filtrów i zdalnym przewijania, znalazłem następujące:

filtrowanie jest uszkodzi powodu tej metody w Ext.data.Store który nazwany jest od nieskończonej scroller kiedy potrzebuje więcej danych z serwera:

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

z jakiegoś powodu ta metoda pożary beforeload wydarzenie bezExt.data.Operation parametr, który ma być jego częścią, jak określono here.

W wyniku wystąpienia błędu w module obsługi onbeforeload w Ext.ux.grid.FiltersFeature bo oczywiście „Opcje” jest niezdefiniowane:

/** 
* @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); 

}, 

mogę wyciąć wywołanie tej metody mask z kodu PagingScroller a następnie funkcja przewijania jest świetna. Mogę przewijać tak szybko, jak mi się podoba i ładuje dane poprawnie. Ale następnie filtry i sortowanie nie zostaną zastosowane do żądań ajax.

Nie nurkowałem tyle w aspekcie sortowania ale myślę, że coś podobnego z tej metody mask ponieważ sortowania jest po prostu kolejnym elementem zawarte przez obiekt operation i powoduje żadnego obiektu działania mają być przekazane do ajax żądanie.

myślę, że gdybym mógł dowiedzieć się, jak zmusić metodę mask ognia beforeload z parametrem operation (jak docs powiedzieć, że ma) wszystko będzie dobrze. Problem polega na tym, że nie byłem w stanie wymyślić, jak to zrobić. Jakieś sugestie?

Jeśli ktoś po prostu powie mi, że się mylę, a ludzie faktycznie wykonali tę pracę, byłbym zainspirowany, ale urywek wszelkich nadpisań, których używałeś do rozwiązania tego problemu, byłby bardzo cenny.

Próbowałem także przejść na wersję 4.0.7 i 4.0.2a i otrzymałem takie same wyniki, więc nie jest to tylko problem związany z wersją beta.

Update - 07 lutego 12:

Wydaje się to rzeczywiście może być problem nie Ext.ux.grid.FilterFeature nieskończona problemem przewijanie. Jeśli usunę konfigurację FilterFeature, całkowicie nieskończone przewijanie działa świetnie i przekazuje parametry sortowania do mojego backendu, gdy sortuję według kolumny. Zacznę zaglądać do końca FilterFeature.

Odpowiedz

14

SUKCES! Mam nieskończenie przewijanie pracy ze zdalnym filtrem i zdalnym sortowaniem (to jest w wersji 4.1 beta 2, ale ponieważ otrzymywałem te same błędy w wersjach 4.02a i 4.0.7, wyobrażam sobie, że to też rozwiąże te problemy). Zasadniczo po prostu musiałem dodać kilka nadpisań w moim kodzie.

Nie testowałem w innych przeglądarkach, ale mam je w FF. Oto nadpisania że używam:

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(); 
    } 
}); 

Mój sklep jest skonfigurowany tak:

// 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 
}); 

Siatka jest:

// 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...], 
}); 

Również początkowe obciążenie musi być zrobione tak (nie tylko store.load()):

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

Twoja odpowiedź pod warunkiem, że właściwy kierunek, ja zmodyfikowany kod z

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

do

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

ten naprawiono problem z poprzedniego filtra zwrotach pustych wyników. Po wprowadzeniu tej zmiany działało poprawnie.

+1

Dobre miejsce. Rozumiem, co mówię, myślę: kiedy sklep odfiltruje do mniej niż zakres gwarancji, wtedy zakres gwarancji utrzymuje się w tej kwocie, a nie ładuje więcej. Problem z rozwiązaniem polega jednak na tym, że zakres gwarancji będzie miał taki sam rozmiar jak sklep i nie zostanie wstępnie pobrany, co oznacza, że ​​gdy sieć zostanie przewinięta w normalny sposób, nigdy nie przeładuje się, gdy minie wiersz 200 lub cokolwiek rozmiar strony to. Dodałem rozwiązanie do nadpisania, po prostu nie jest ono zbyt dynamiczne. Zmienna gwarancjiRange ustawiła się na 100 statyczną, ponieważ taka jest moja. – Geronimo

Powiązane problemy