2013-01-20 6 views
5

tl; dr wykonywania podstawowych paginacji w Firebase poprzez startAt, endAt i limit jest strasznie skomplikowane, nie musi być łatwiejszy sposób.Stronicowanie chronologicznie priorytet Firebase dzieciom

Tworzę interfejs administracyjny dla dużej liczby zgłoszeń użytkowników. Moim początkowym (i aktualnym) pomysłem jest po prostu pobranie wszystkiego i wykonanie paginacji na kliencie. Istnieje jednak zauważalne opóźnienie podczas pobierania 2000+ rekordów (zawierających po 5-6 małych liczb/pól ciągów), które przypisuję do ładunku danych powyżej 1,5 miliona.

Obecnie wszystkie wpisy są dodawane za pośrednictwem push, ale jestem trochę zagubiony, jak paginować się przez ogromną listę.

Aby pobrać pierwszą stronę danych używam endAt z limit 5:

ref.endAt().limit(10).on('child_added', function(snapshot) { 
    console.log(snapshot.name(), snapshot.val().name) 
}) 

co powoduje następujące:

-IlNo79stfiYZ61fFkx3 #46 John 
-IlNo7AmMk0iXp98oKh5 #47 Robert 
-IlNo7BeDXbEe7rB6IQ3 #48 Andrew 
-IlNo7CX-WzM0caCS0Xp #49 Frank 
-IlNo7DNA0SzEe8Sua16 #50 Jimmmy 

Po pierwsze, aby dowiedzieć się, jak wiele stron tam Czy prowadzę oddzielny licznik, który jest aktualizowany za każdym razem, gdy ktoś dodaje lub usuwa rekord.

drugie ponieważ używam push nie mam sposobu nawigowania do konkretnej strony, ponieważ nie wiem, nazwę ostatniego rekordu do konkretnej strony oznaczającego interfejs jak ten nie jest obecnie możliwe:

Standard pagination controls

Aby było to łatwiejsze, zdecydowałem się na posiadanie przycisków następnych/poprzednich, ale to również stanowi nowy problem; jeśli mogę użyć nazwy pierwszego rekordu w poprzednim wynik-set mogę paginate do następnej strony przy użyciu następujących:

ref.endAt(null, '-IlNo79stfiYZ61fFkx3').limit(5).on('child_added', function(snapshot) { 
    console.log(snapshot.name(), snapshot.val().name) 
}) 

Wynikiem tej operacji jest następująca:

-IlNo76KDsN53rB1xb-K #42 William 
-IlNo77CtgQvjuonF2nH #43 Christian 
-IlNo7857XWfMipCa8bv #44 Jim 
-IlNo78z11Bkj-XJjbg_ #45 Richard 
-IlNo79stfiYZ61fFkx3 #46 John 

teraz Mam następną stronę, z wyjątkiem przesunięcia o jedną pozycję, co oznacza, że ​​muszę dostosować mój limit i zignorować ostatni rekord.

Aby cofnąć jedną stronę, będę musiał zachować osobną listę klientów każdego rekordu, jaki otrzymałem do tej pory, i dowiedzieć się, jaką nazwę przejść na startAt.

Czy jest to łatwiejszy sposób, czy powinienem wrócić do pobierania wszystkiego?

Odpowiedz

7

Pracujemy nad dodaniem zapytania "offset()", aby umożliwić łatwą paginację. Będziemy także dodawać specjalny punkt końcowy, aby umożliwić odczytanie liczby dzieci w danej lokalizacji bez faktycznego ładowania ich z serwera.

Obie te rzeczy będą jednak wymagać trochę więcej. W międzyczasie metoda, którą opisujesz (lub robi to wszystko na kliencie) jest prawdopodobnie najlepszym rozwiązaniem.

Jeśli posiadasz strukturę danych, która jest tylko dopisywana, możesz potencjalnie również wykonywać podział na strony podczas zapisywania danych. Na przykład: umieść pierwsze 50 w/strona 1, umieść drugie 50 w/strona2 itd.

+2

Dzięki, offset() i count() rozwiążą wszystkie problemy z dzieleniem na strony. –

+0

Dowolna aktualizacja dotycząca tego, kiedy te funkcje zostaną udostępnione dla JavaScript API - w szczególności z obsługą powiązań AngularFire? –

+0

+1 dla pytania z @DanKanze. Byłoby świetnie, zwłaszcza w AngularFire. – Jake

4

Innym sposobem jest z dwóch drzew:

drzewiastą ID: { ID1: ID1 ID2: ID2, id3: id3 }

drzewa danych: { ID1 : ... ID2: ... id3: ... }

następnie można załadować całe drzewo identyfikatorów (lub spory kawałek It) do klienta, a nie z ozdobnego paginacji to tr ee z ids.

2

Oto hack na paginację w każdym kierunku.

// get 1-5 
ref.startAt().limit(5) 

// get 6-10 from 5 
ref.startAt(null, '5th-firebase-id' + 1).limit(5) 

// get 11-15 from 10 
ref.startAt(null, '10th-firebase-id' + 1).limit(5) 

Zasadniczo jest to hack dla startAtExclusive(). Możesz wszystko na końcu identyfikatora.

Ustalono również, że należy cofnąć się o endAtExclusive().

// get 6-10 from 11 
ref.endAt(null, '11th-firebase-id'.slice(0, -1)).limit(5)... 

// get 1-5 from 6 
ref.endAt(null, '6th-firebase-id'.slice(0, -1)).limit(5)... 

Będzie grać z tym nieco więcej, ale wydaje się działać z identyfikatorami push. Zastąp limit wartości limitToFirst lub limitToLast, jeśli używasz zapytań firebase.