2015-05-03 8 views
35

Desidero memorizzare nella cache il risultato di una query nei dati ember. (findQuery)Come memorizzare nella cache il risultato della query nei dati di brace

Per rendere più chiaro: non voglio memorizzare in cache tutti i modelli; solo quali sono i modelli i risultati della query. Dov'è il posto giusto per questo?

Stavo pensando di implementarlo nell'adattatore e memorizzare il risultato della chiamata AJAX, ma non penso che questa sia una buona soluzione dato che non voglio sovrascrivere il modello caricato e forse più recente e/o modificato dati.

Non credo sia possibile restituire solo un elenco di ID e per manipolare l'adattatore e il serializzatore per questo semplice caso d'uso sembra essere disordinato!

In realtà non desidero che lo findQuery venga chiamato per tipi specifici di query. Come il comportamento di findAll. Bello sarebbe qualcosa come un amo queryShouldBeCached.

C'è una buona soluzione per questo?

+0

Dove stai utilizzando la cache, ad esempio su una particolare rotta, e la cache verrebbe cancellata quando la query è stata rieseguita o c'è una transizione dalla rotta? – aceofspades

+0

c'è una transizione dal percorso.Il caso d'uso è che visualizzo un elenco di risultati di ricerca, l'utente fa clic su un risultato e passa alla pagina dei dettagli. se torna indietro non voglio rieseguire la ricerca che costa quasi 5 secondi. – Lux

+1

Mi aggancio nei ganci 'setupController' e' deactivate' del percorso, dove prendo un riferimento al controller e memorizzo i record completi. Nel mio caso li distruggo quando esco, quindi dovresti considerare come attivare una pulizia posticipata. Credo che appartenga alla route/controller, piuttosto che all'adattatore che è più di una cosa astratta/globale. In questo modo è contenuto per la funzione specifica (ricerca). – aceofspades

risposta

0

Quando si attiva una richiesta basata sui parametri, Ember Data non sa come questi parametri si traducono necessariamente nei modelli (ovvero non sa che si dispone di tutti i record che hanno una sorta di relazione param1). Puoi metterlo nella cache tu stesso, ma poi avresti ancora bisogno di un qualche modo per conoscere quei record di altri record nel tuo negozio.

+1

Lo so perché il parametro che sto filtrando non è modificabile dall'utente. Ma come posso nasconderlo? Supponiamo di voler memorizzare nella cache tutte le richieste di query. – Lux

1

Non sono un esperto di Ember ma penso che sia possibile risolvere il problema con una soluzione JS pura.

Dati restituiti da Ember Data restituiscono Promises, ad es. return this.store.findAll('blog-post'); // => Promise, è possibile memorizzare le promesse nella cache in un oggetto semplice con funzioni di ordine superiore (funzioni che restituiscono funzioni). La cache degli oggetti potrebbe essere sostituita con localStorage, sessionStorage, Map o anche WeakMap ma sto utilizzando la cache degli oggetti per semplificare le cose.

Che cosa si vuole essenzialmente fare è sostituire seguente chiamata:

return this.store.findAll('blog-post'); 

con qualcosa di più o meno come:

return cachedStore.findAll('blog-post'); 

in realtà, con la soluzione qui di seguito potrebbe apparire più simile a:

return cachedStore.call(this, 'findAll', 'blog-post'); 

Di conseguenza, si richiederà una volta i dati e si ritornerà sempre dalla cache in s chiamate successive.

mi permetta di mostrare come l'implementazione potrebbe essere simile:

var cachedStore = (function() { 
    // Your cache - in this case simple object literal 
    var cache = {}; 

    // Actual method that will check cache for results before trying to query services 
    return function (method) { 
    var args = Array.prototype.slice.call(arguments, 1); 
    var serializedArgs = JSON.stringify(args); 

    if (!(serializedArgs in cache)) { 
     cache[serializedArgs] = this.store[method].apply(this, args); 
    } 
    return cache[serializedArgs]; 
    }; 
}()); 

Ed ecco un esempio dell'uso:

// Fires a request 
cachedStore.call(this, 'findAll', 'blog-post'); 
// Returns from cache 
cachedStore.call(this, 'findAll', 'blog-post'); 
// Returns from cache 
cachedStore.call(this, 'findAll', 'blog-post'); 

// Fires a request 
cachedStore.call(this, 'findRecord', 'blog-post', 123); 
// Returns from cache 
cachedStore.call(this, 'findRecord', 'blog-post', 123); 
// Returns from cache 
cachedStore.call(this, 'findRecord', 'blog-post', 123); 

Ritiene che l'aiuto in qualche modo?

+0

Avremmo potuto rendere l'API molto più bello di 'cachedStore.call (this, 'findAll', ...)', ad es. 'This.cachedStore.findAll (...)'. L'ho fatto in questo modo perché non sapevo esattamente dove esattamente nella tua applicazione vuoi aggancio con le cache (solo file singolo? Un'intera applicazione?). Inoltre, potresti voler esplorare le cose ancora di più e far scadere automaticamente i risultati dopo un determinato periodo di tempo. Ci sono molte opzioni inesplorate nell'esempio sopra, volevo solo mostrare la direzione. Se qualcosa ha bisogno di ulteriori spiegazioni, per favore fatemelo sapere –

Problemi correlati