Kev*_*vin 6 knockout.js single-page-application breeze
我有一个名为Item的类,它被PeriodId过滤.有很多时期 - 但我们只需要一次看一个.我想向用户显示初始数据加载(例如,PeriodId == 1).然后,我希望用户能够在其他时段查询/过滤.
如果用户选择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;
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
结合Jay的建议,(我必须将'param'重命名为'pId','q'重命名为'query',如果forceRemote == true则重置queryParamCache,并且我必须在'breeze'前面添加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;
}
Run Code Online (Sandbox Code Playgroud)
一个更简单的想法可能只是缓存关于您是否已执行查询的事实.而不是使用executeQueryLocally方法,在这种情况下,更容易使用指定FetchStrategy的能力.请注意,使用 FetchStrategy.FromLocalCache时,您仍会获得一个承诺,但该承诺将立即执行.好的部分是您不必以不同方式处理远程与本地查询.
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);
}
Run Code Online (Sandbox Code Playgroud)
此方法的另一个特性是它还处理"远程"查询不返回任何记录的情况.因此,与测试本地查询是否实际返回数据不同,当您尚未运行查询时以及当没有数据满足查询时这将是假的,此方法只是跟踪您是否曾执行过查询,不管其结果如何.