2013-04-03 7 views
6

Ich habe eine Klasse namens Item, die von PeriodId gefiltert wird. Es gibt viele Perioden - aber wir müssen nur einen nach dem anderen betrachten. Ich möchte dem Benutzer eine anfängliche Datenlast präsentieren (sagen wir wo PeriodId == 1). Ich möchte dann, dass der Benutzer andere Zeiträume abfragen/filtern kann.Breezejs - Muster für Abfragen lokaler Cache

Wenn der Benutzer PeriodId == 2 auswählt, möchte ich, dass der EntityManager den lokalen Cache abfragt, und wenn die Daten vorhanden sind, geben Sie diese Daten zurück. Wenn es sich nicht im lokalen Cache befindet, möchte ich, dass es den Server abfragt, und füge den Satz mit PeriodId == 2 zum Cache hinzu. Wenn der Benutzer dann auf PeriodId == 1 klickt, sollten sich diese Daten bereits im Cache und nicht auf dem Server befinden.

Mit dem unten stehenden Code treffe ich den Server jedes Mal, wenn ich einen Zeitraum auswähle (auch wenn ich einfach hin und her wechsle). Gibt es ein Muster, das dies löst ... Ich kenne die Primärschlüssel hier NICHT.

var getItems = function (myObservable, periodId, forceRemote) { 

    var pId = periodId ? periodId : 1; 

    var query = entityQuery.from('Item') 
     .orderBy(orderBy.items) 
     .where("PeriodId", "==", pId); 

    if (!forceRemote) { 
     var r = getLocal(query); 
     if (r) { 
      if (r.length > 3) { 
       myObservable(r); 
       return Q.resolve(); 
      } 
     } 
    } 

    return manager.executeQuery(query) 
     .then(querySucceeded) 
     .fail(queryFailed); 

    function querySucceeded(data) { 
     if (myObservable) { 
      myObservable(data.results); 
     } 
    } 
}; 

function getLocal(query) { 
    try { 
     return manager.executeQueryLocally(query); 
    } catch(e) { 
     // set was not found in local cache, return null - forcing trip to server 
     return null; 
    } 
} 

UPDATE:

Jay Vorschlag Einbeziehung, (ich hatte 'param' auf 'pId', 'q' zu 'query' umbenennen, setzen Sie das queryParamCache wenn forceRemote == true, und ich hatte das FetchStrategy mit vorangestellt wird) ‚Brise.‘:

var queryParamCache = {}; 

var getItems = function(myObservable, periodId, forceRemote) { 

    if (forceRemote) { 
     queryParamCache = {}; 
    } 

    var pId = periodId ? periodId : 1; 

    var query = entityQuery.from('Item') 
     .orderBy(orderBy.items) 
     .where('PeriodId', '==', pId); 

    var isInCache = queryParamCache[pId]; 

    if (isInCache && !forceRemote) { 
     query = query.using(breeze.FetchStrategy.FromLocalCache); 
    } else { 
     queryParamCache[pId] = true; 
     query = query.using(breeze.FetchStrategy.FromServer); 
    } 

    return manager.executeQuery(query) 
     .then(querySucceeded) 
     .fail(queryFailed); 

    function querySucceeded(data) { 
     rosterObservable(data.results); 
    } 
}; 

function queryFailed(error) { 
    var msg = 'Error retreiving data. ' + error.message; 
    logError(msg, error); 
    throw error; 
} 

Antwort

6

Eine einfachere Idee könnte nur die Tatsache cachen sein, ob Sie die Abfrage durchgeführt haben oder nicht. Und anstatt die Methode executeQueryLocally zu verwenden, ist es in diesem Fall einfacher, die Möglichkeit zu verwenden, eine FetchStrategy anzugeben. Beachten Sie, dass Sie bei der Verwendung von FetchStrategy.FromLocalCache immer noch eine Zusage erhalten, aber diese Zusage wird tatsächlich sofort ausgeführt. Der nette Teil ist, dass Sie Remote vs lokale Abfragen nicht anders behandeln müssen. Das andere Merkmal dieses Ansatzes ist, dass es auch den Fall behandelt, in dem die "entfernte" Abfrage keine Datensätze zurückgibt. Anders als beim Testen, ob die lokale Abfrage tatsächlich Daten zurückgibt, die falsch sind, wenn Sie die Abfrage noch nicht ausgeführt haben, und , wenn keine Daten die Abfrage erfüllen, verfolgt dieser Ansatz einfach, ob Sie jemals ausgeführt haben die Abfrage, unabhängig von ihren Ergebnissen.

+0

Brilliant, Jay! Ein paar Verbesserungen und es hat funktioniert ... Ich werde meine Frage mit den Änderungen, die ich gemacht habe, aktualisieren. Vielen Dank! – Kevin

Verwandte Themen