0

我在我的 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 没有发送我的值为空的属性。希望我很清楚。

4

1 回答 1

1

我想我有一个理论。默认情况下,Breeze Web API 控制器上的 JSON.Net 序列化程序不返回nulls 。

当数据从查询中到达时,Breeze 将接收到的值合并到现有实体中……逐个属性。你能看出问题吗?跟我来:

  1. 您使用 id=1 查询 Foo

  2. 接收到的 JSON 是{id: 1, name: "Foo"}并且 Breeze 设置物化 Foo 实体的相应属性

  3. 服务器上的某些东西将名称更改为“Bar”;你重新查询

  4. 接收到的 JSON 是{id: 1, name: "Bar"};Foo 实体现在是 {id:1, name: "Bar"}

  5. 服务器上的某些东西将名称更改为null;你重新查询

  6. 收到的 JSON 是{id: 1}属性 没有值name!!!

  7. Breeze 合并这些值。但是没有name合并的价值,所以当然name保留它以前的价值。

  8. Foo 实体仍然是 {id:1, name: "Bar"} 而服务器等价物是 {id:1, name: null}

我能想到的一种解决方法是重新配置 JsonFormatter 以发送空值。另一种方法是为这个特定的用例编写一个自定义的 JsonResultsAdapter ......一个检测缺失的属性(例如,name)并将它们添加到节点,在这种情况下使用空值。

这种情况让我质疑我们决定默认抑制空值是否明智。我会和团队一起提出这个问题。

于 2013-06-08T06:37:11.827 回答