2013-04-03 3 views
6

У меня есть класс Item, который фильтруется PeriodId. Есть много периодов - но нам нужно только смотреть по одному. Я хочу представить пользователю исходную нагрузку (скажем, где PeriodId == 1). Затем я хочу, чтобы пользователь мог запрашивать/фильтровать в другие периоды.Breezejs - шаблон для запроса локального кеша

Если пользователь выбирает PeriodId == 2, я хочу, чтобы entityManager запрашивал локальный кеш, и если данные там, верните эти данные. Если он не находится в локальном кеше, я хочу, чтобы он запрашивал сервер и добавлял в кэш набор, где PeriodId == 2. Если пользователь затем нажимает на PeriodId == 1, эти данные должны быть уже в кеше, а не в оба конца на сервер.

Используя приведенный ниже код, я поражаю сервер каждый раз, когда я выбираю период (даже если я просто переключаюсь взад-вперед). Есть ли образец, который решает это ... Я НЕ знаю первичные ключи здесь.

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:

Включение предложения Джея, (я должен переименовать 'параметров' на 'Pid', 'д' на 'запрос', сбросить queryParamCache если forceRemote == верно, и Я должен был предварять FetchStrategy с) «ветер».:

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

ответ

6

Более простая идея может быть просто кэшировать факт, чтобы ли вы выполнили запрос или нет. И вместо того, чтобы использовать метод executeQueryLocally, в этом случае проще использовать возможность определять FetchStrategy. Обратите внимание, что при использовании FetchStrategy.FromLocalCache вы по-прежнему получите обещанное обещание, но это обещание действительно будет выполнено немедленно. Приятная часть заключается в том, что вам не нужно обрабатывать удаленные vs локальные запросы по-разному.

var queryParamCache = {}; 
var getItemsPromise = function (periodId, forceRemote) { 

    var pId = periodId ? periodId : 1; 

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


    var isInCache = queryParamCache[pId]; 
    if (isInCache && !forceRemote) { 
     q = q.using(FetchStrategy.FromLocalCache); 
    } else { 
     queryParamCache[pId] = true; 
     q = q.using(FetchStrategy.FromServer); 
    } 
    return manager.executeQuery(q); 
} 

Другой особенностью этого подхода является то, что она также имеет дело со случаем, когда «удаленный» запрос не возвращает никаких записей. Таким образом, в отличие от проверки того, действительно ли локальный запрос фактически возвращает данные, что будет ложным, когда вы еще не выполнили запрос и , когда нет данных, удовлетворяющих запросу, этот подход просто отслеживает, выполнялись ли вы когда-либо запрос, независимо от его результатов.

+0

Блестящий, Jay! Несколько настроек, и это сработало ... Я уточню свой вопрос с изменениями, которые я сделал. Благодаря! – Kevin

Смежные вопросы