导入期间为使用ko.observableArray()
属性扩展的实体运行时出错,而不是在构造函数中作为简单数组[]
类型进行扩展。
var customerCtor = function () {
this.extendedProp = ko.observable(true);
//this.extendedArray = ko.observableArray(); // causes error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
this.extendedArray = []; // this works just fine
};
我在Breeze v1.3.6 DocCode旁边创建了一个测试:exportImportTests.js“在本地存储整个缓存并恢复”作为我的起点,这是新的测试:
test("w/extended Customer, stash entire cache locally and restore", 3, function () {
var em1 = newEm();
var store = em1.metadataStore;
// extend Customer with observables
var customerCtor = function () {
this.extendedProp = ko.observable(true);
this.extendedArray = ko.observableArray(); // causes error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
//this.extendedArray = []; // but this will work just fine?
};
store.registerEntityTypeCtor("Customer", customerCtor);
var expected = testData.primeTheCache(em1);
// grab first Customer, push value onto extendedArray prop
var custEntity = em1.getEntities(expected.customerType)[0];
custEntity.extendedArray().push('some-value'); // even when defined as [], Breeze re-writes field as ko.observable
var exportData = em1.exportEntities();
var stashName = "stash_everything";
window.localStorage.setItem(stashName, exportData);
var importData = window.localStorage.getItem(stashName);
var em2 = new EntityManager(); // virginal - so register ctor on this instance
var store2 = em2.metadataStore;
store2.registerEntityTypeCtor("Customer", customerCtor);
em2.importEntities(importData);
var entitiesInCache = em2.getEntities();
var restoreCount = entitiesInCache.length;
equal(restoreCount, expected.entityCount,
"should have restored expected number of all entities");
var restoredCustomer = em2.getEntities(expected.customerType)[0];
ok(restoredCustomer.extendedProp(), 'extended property present');
ok(restoredCustomer.extendedArray().length > 0, 'extended Array present and has data');
});
em2.importEntities(importData);
会抛出错误:
Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
at Error (<anonymous>)
at h [as extendedArray] (http://localhost:47595/Scripts/knockout-2.2.1.js:44:167)
at ctor.initializeEntityPrototype.proto.setProperty (http://localhost:47595/Scripts/breeze.debug.js:14634:31)
at updateTargetPropertyFromRaw (http://localhost:47595/Scripts/breeze.debug.js:13062:24)
at aspectName (http://localhost:47595/Scripts/breeze.debug.js:13025:13)
at Array.forEach (native)
at updateTargetFromRaw (http://localhost:47595/Scripts/breeze.debug.js:13023:19)
at em._inKeyFixup (http://localhost:47595/Scripts/breeze.debug.js:12601:17)
at Array.forEach (native)
at importEntityGroup (http://localhost:47595/Scripts/breeze.debug.js:12568:28)
由于Breeze总是重写构造函数字段(在我的情况下为KO),定义为[]
有效。但不确定为什么在预定义属性时会发生这种情况?
有人碰到这个,或者我错过了某处的文档说明?
答案 0 :(得分:1)
我们会看一下。
是的,Breeze假设构造函数中添加的每个属性都应该根据当前的“模型库”进行重写,在您的情况下,它是KO。因此,毫不奇怪数组成为ko.observableArray。
此外,由于这样的属性被认为是在Breeze的管辖范围内,我们必须将它与Breeze可观察性和序列化机制联系起来,这意味着我们将其重新编写为Breeze风格的可观察数组。这样的数组是计算的。
显然,我们为“未映射”的属性执行此操作的方式存在一些问题。我们来看看。
N.B。:我假设(并且您的代码确认)数组属性extendedArray
是Breeze意义上的“未映射属性”。那应该没问题。
您不应该在构造函数中提及映射的集合导航属性。没有正当理由这样做我能想到的。在构造函数中提及映射属性的主要原因是(a)为其提供默认值或(b)使其可用于自定义(未映射)计算属性。集合导航属性没有合理的替代默认值(默认为空),将它包含在计算中是很少/可避免的。