保持一个新的缓存
您在 10 月 31 日的评论提醒我,您可以保持资源新鲜并使用缓存。这不是“非此即彼”!
只需执行以下操作:
- 在使用它之前总是重新查询该资源(例如,当您的 ViewModel 加载视图时)
- 在发出该查询之前清除该资源类型的所有实例的缓存。
您可以将这两种想法都封装在您的datacontext.getXXX
方法中。这就是我的意思:
// 清除发票缓存后获取新发票,可选择过滤
函数getInvoices(可选谓词){
clearCachedInvoices();
var 查询 = 微风.EntityQuery.from('Invoices');
if (optionalPredicate) { query = query.where(predicate); }
返回 manager.executeQuery(query).then(_logSuccess, _queryFailed);
}
// 刷新特定发票
功能刷新发票(发票){
// Todo: 添加参数错误检查?
var 查询 = 微风.EntityQuery.fromEntities([invoice]);
返回 manager.executeQuery(query).then(success, _queryFailed);
功能成功(数据){
_logSuccess(数据);
返回数据.结果[0];// 查询返回数组;来电者想要第一个。
}
}
函数 clearCachedInvoices() {
var cachedInvoices = manager.getEntities('Invoice'); // 缓存中的所有发票
// Todo: 这应该是 Breeze EntityManager 本身的一个函数
cachedInvoices.forEach(function (entity) { manager.detachEntity(entity); });
}
关于缓存清除的重要注意事项
我首先清除缓存的原因是另一个用户可能已经删除了您之前检索到的一些发票。我假设您希望将它们从缓存中删除,以便用户只能看到实时发票。
如果无法删除发票(例如,您执行“软删除”而不是将发票标记为“非活动”),则不需要此缓存清除步骤(以及随之而来的问题)。我个人对删除非常警惕,因为它们会导致各种问题。我更喜欢软删除。
您需要确保 UI 没有保留以前的发票实体。你已经要求经理重新开始。这意味着每个现有的发票实体引用都指的是一个分离的实体。查询后,每个缓存的发票都是一个新实例。
清除缓存的另一个危险是它会清除所有未决的发票更改。如果您可能有未保存的发票更改(新的、更新的或计划的删除),您不希望运行此方法。您可能希望添加保护逻辑以防止丢失未保存的更改。该逻辑究竟是什么将是特定于应用程序的。它可能会涉及调用manager.hasChanges('Invoice')
.
如果您始终刷新与发票有关的所有内容,则不必担心丢失参考。
这些约束应该很容易满足您的要求。它们与您最初所说的非常一致:您真的不想缓存。所以这应该是小菜一碟......只需使用上面显示的代码,您就可以轻松获得缓存的好处。
啊......但我不禁想到实际上想要刷新实体对象而不是完全替换它们的人。也许她想在用户有未保存的更改时刷新。然而,她想删除已被其他用户删除的实体。
好吧,我也有她的食谱。
功能 refreshAllInvoices(已删除){
// 移除的是调用者的数组,应该填充实体
// 我们从缓存中删除;它填充在下面的成功方法中。
var cached = manager.getEntities('Invoice'); // 获取缓存中的所有发票
return 微风.EntityQuery.from('Invoices')
.using(manager).execute(成功,_queryFailed);
函数成功(){
删除.长度 = 0; //清空数组
var 结果 = data.results; // 查询结果
// 从“缓存”数组中删除每个结果
results.forEach(函数(实体){
var ix = cached.indexof(entity);
if (ix > -1) { 缓存[ix] = null; }
});
// 剩下的必须在服务器上删除
// 或者是一个我们还没有保存的新实体
// 循环遍历,分离我们认为已经被删除的那些。
cached.forEach(函数(实体){
如果(实体!== null &&
!entity.entityAspect.entityState.isAdded()) {
移除.push(实体);// 让调用者知道这个
manager.detachEntity(实体);
}
});
返回结果;
}
}