2013-01-20 15 views
5

tl; dr Performing impaginazione di base Firebase via startAt, endAt e limit è terribilmente complicato, ci deve essere un modo più semplice.impaginazione cronologicamente ordine di priorità i bambini Firebase

Sto costruendo un'interfaccia di amministrazione per un numero elevato di invii di utenti. La mia idea iniziale (e attuale) è di recuperare semplicemente tutto ed eseguire la paginazione sul client. Vi è tuttavia un ritardo notevole quando si recuperano più di 2000 record (contenenti 5-6 piccoli numeri/campi di stringhe ciascuno) che attribuisco a un carico di dati di oltre 1,5 MB.

Attualmente tutte le voci vengono aggiunte tramite push ma sono un po 'perso per quanto impaginato attraverso l'enorme elenco.

a prendere la prima pagina di dati che sto utilizzando endAt con una limit 5:

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

che si traduce nella seguente:

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

In primo luogo per capire quante pagine ci sto mantenendo un contatore separato che viene aggiornato ogni volta che qualcuno aggiunge o rimuove un record.

In secondo luogo dal momento che sto usando push non ho modo di navigazione verso una pagina specifica in quanto non conosco il nome dell'ultimo record per una pagina specifica che significa un'interfaccia come questo non è possibile:

Standard pagination controls

Per semplificare, ho deciso di passare semplicemente ai pulsanti Avanti/Indietro, ma questo presenta anche un nuovo problema; se uso il nome del primo record nel precedente set di risultati posso impaginare alla pagina successiva utilizzando il seguente:

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

Il risultato di questa operazione è la seguente:

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

Ora Ho la pagina successiva, tranne che è spostata di una posizione, il che significa che devo regolare il mio limite e ignorare l'ultimo record.

Per tornare indietro di una pagina Dovrò mantenere un elenco separato sul client di ogni record che ho ricevuto finora e capire quale nome passare a startAt.

C'è un modo più semplice per farlo o dovrei semplicemente tornare a recuperare tutto?

risposta

7

Stiamo lavorando per aggiungere una query "offset()" per consentire una facile impaginazione. Aggiungeremo anche un endpoint speciale per consentire di leggere il numero di bambini in una posizione senza caricarli effettivamente dal server.

Entrambi ci vorranno un po '. Nel frattempo, il metodo che descrivi (o che fai tutto sul client) è probabilmente la soluzione migliore.

Se si dispone di una struttura dati che è solo append, è possibile che l'impaginazione venga eseguita anche durante la scrittura dei dati. Ad esempio: inserisci il primo 50 in/page1, inserisci il secondo 50 in/page2, ecc.

+2

Grazie, offset() e count() risolveranno tutti i problemi di impaginazione. –

+0

Qualsiasi aggiornamento su quando queste funzionalità saranno rilasciate per l'API JavaScript - In particolare con il supporto per i collegamenti AngularFire? –

+0

+1 per la domanda da @DanKanze. Sarebbe fantastico, specialmente per AngularFire. – Jake

4

Un altro modo per farlo è con due alberi:

albero di ID: { id1: id1, id2: id2, ID3: ID3 }

Albero dei dati: { ID1 : ..., ID2: ..., ID3: ... }

è possibile quindi caricare l'intero albero di iD (o una grossa fetta di esso) al client, e fare impaginazione fantasia con che tr ee di ids.

2

Ecco un trucco per impaginare in ciascuna direzione.

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

Fondamentalmente è un hack per startAtExclusive(). Puoi qualsiasi cosa alla fine dell'ID.

Anche risolto endAtExclusive() per andare indietro.

// 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)... 

Giocherò con questo un po 'di più, ma sembra funzionare con gli ID push. Sostituire il limite con limitToFirst o limitToLast se si utilizzano query Firebase.

Problemi correlati