我们有一个具有三个关键字段的实体,其中一个是日期(不要问 - 它是一个没有其他明显键的摘要视图)。
在将更改保存到上述实体后处理来自服务器的响应时,Breeze 抛出“此密钥已附加”错误。
保存更改后, MergeEntity中会出现问题。似乎初始查找未能在客户端上找到实体,因此它尝试再次添加它导致错误。
在 MergeEntity 的顶部附近,我们发现以下行...
var entityKey = EntityKey._fromRawEntity(node, entityType);
...返回一个 entityKey._keyInGroup == "1535:::44::: 2013-02-28T11:00:00.000Z "。请注意看起来像 JSON 日期字符串的第三个关键字段。
后来,当新实体(错误地)创建其 entityKey._keyInGroup == "1535:::44::: Fri Mar 01 2013 00:00:00 GMT+1300 (New Zealand Daylight Time) "时。现在第三个字段看起来像一个真正的 JavaScript 日期。
当我们点击这条线时,错误终于发生了......
attachEntityCore(em, targetEntity, EntityState.Unchanged);
...获取“此密钥已附加”错误,因为我们刚刚保存的实体显然一直在客户端缓存中。
更新:我对 Breeze 的破解让这个工作......
1) 我更改了 _ fromRawEntity函数以检查日期并正确转换它们,以便我们获得稍后为真实实体生成的相同键值。(此代码是从updateEntity函数复制的,因此行为应该相同)。
ctor._fromRawEntity = function (rawEntity, entityType) {
var keyValues = entityType.keyProperties.map(function (p) {
var val = rawEntity[p.nameOnServer];
if (p.dataType.isDate && val) {
if (!__isDate(val)) {
val = DataType.parseDateFromServer(val);
}
}
return val;
});
return new EntityKey(entityType, keyValues);
};
2) Breeze 现在在保存更改后找到了实体,但是......当 Breeze 尝试使用从服务器返回的值更新实体属性时,我得到了一个错误。我怀疑这是由于defaultPropertyInterceptor函数中的一个问题,该函数正在检查属性值是否已更改...
// exit if no change
if (newValue === oldValue) {
return;
}
比较日期时,这将始终返回 false,因此我将这一行修改为:
if (newValue === oldValue || (dataType && dataType.isDate && newValue && oldValue && newValue.valueOf() === oldValue.valueOf())) {
return;
}
从我最初的测试来看,一切似乎都在工作,但我非常感谢那些更熟悉微风的人的任何想法:)
更新:也许最后一个片段会更轻松,因为......
// exit if no change
var comparable = dataType && getComparableFn(dataType);
if (newValue === oldValue || (comparable && comparable(newValue) === comparable(oldValue))) {
return;
}
...尽管考虑到它在每个属性集中运行,这增加了一些代码。