我们有一个包含三个关键字段的实体,其中一个是日期(不要问 - 它是一个没有其他明显键的摘要视图)。
在将更改保存到上述实体后处理来自服务器的响应时,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(新西兰夏令时) ”。现在第三个字段看起来像一个真正的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;
}
...虽然考虑到它在每个属性集中运行,但会增加更多代码。
答案 0 :(得分:0)
修改:这已在Breeze v1.3.0中修复,现已上市。
同意,这是一个错误!它将在下周初发布,下周初发布。 (我们现在有一个测试,它将日期作为主键的一部分:)
并感谢您查找,分析和报告它。分析确实有帮助。