我在我的 Durandal SPA 项目中使用 Breeze。
我的搜索结果页面中有一个元素列表。每当用户单击 1 个元素时,我都会查询服务器以确保该项目没有被其他人锁定。如果是这种情况,那么我会显示一个模式对话框来警告用户当前谁在锁定该项目。
它适用于以下第一种情况:
场景一:
- t:元素 E 未锁定。
- t+1:在我的搜索结果页面中点击了元素 E
- t+2:查询服务器以检查是否锁定了该元素(结果:未锁定)
- t+3:显示元素 E 的详细信息页面
场景二:
- t:元素 E 未锁定。
- t+1:在我的搜索结果页面中点击了元素 E
- t+2:查询服务器以检查该元素是否锁定(结果:被 John 锁定)
- t+3:显示模态弹出窗口以警告用户 John 锁定了该元素
- t+4:约翰释放元素 E
- t+5:在我的搜索结果页面再次点击元素E
- t+6:查询服务器以检查该元素是否锁定(结果:被 Paul 锁定)
- t+7:显示模态弹窗以警告用户 Paul 锁定了该元素
- t+8: Paul 释放元素 E
(所以此时没有人锁定元素——> LockedBy 应该为空)
- t+9:在我的搜索结果页面再次点击元素E
- t+10:查询服务器以检查该元素是否锁定(结果:被 Paul 锁定)<- !!!!
如您所见,问题发生在第二种情况的第 10 步。似乎每当值为空(LockedBy)时,微风仍在使用该属性的旧值?!
任何的想法?
下面是我用 Breeze 查询服务器的代码:
var getTransportById = function (transportId, transportObservable) {
// Input: transportId: the id of the transport to retrieve
// Output: transportObservable: an observable filled with the transport
var query = entityQuery.from('Transports')
.where('id', '==', transportId)
.expand("Sender.City, Sender.City.Country, Receiver.City, Receiver.City.Country, Insurances, Client.City, Client.City.Country, LockedBy");
query = query.using(breeze.FetchStrategy.FromServer);
return manager.executeQuery(query)
.then(querySucceeded)
.fail(queryFailed);
function querySucceeded(data) {
transportObservable(data.results[0]);
}
};
下面是我的模型的减法:
public class Transport
{
[Key]
public int Id { get; set; }
public string TransportNumber { get; set; }
public string Remark { get; set; }
public int? LockedById { get; set; }
public DateTime? LockedTime { get; set; }
public virtual User LockedBy { get; set; }
}
PS:在我的浏览器中分析流量数据时,似乎Breeze在为null时没有发送任何导航属性数据。因此,在我的场景中,客户端缓存中的值变得不正确,因为其他人(另一个会话中的另一个用户)更改了此数据并且我的客户端缓存没有正确刷新,因为 Breeze 没有发送我的值为空的属性。希望我很清楚。