1

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),因此定义为[]有效。但不确定为什么在预定义属性时会发生这种情况?

有人遇到过这个问题,还是我在某处错过了文档说明?

4

1 回答 1

1

我们会看看它。

是的,Breeze 假设在构造函数中添加的每个属性都应该按照流行的“模型库”重写,在你的情况下,它是 KO。因此,数组变成 ko.observableArray 也就不足为奇了。

此外,因为这样的属性被假定在 Breeze 的管辖范围内,我们必须将它绑定到 Breeze 可观察性和序列化机制中,这意味着我们将其重写为 Breeze 风格的可观察数组。这样的数组是计算出来的。

显然,我们为“未映射”的属性执行此操作的方式存在一些问题。我们会看看那个。

注意:我假设(并且您的代码确认)数组属性extendedArray是 Breeze 意义上的“未映射属性”。那应该没问题。

您不应在构造函数中提及映射集合导航属性。没有正当理由这样做,我可以想到。在构造函数中提及映射属性的主要原因是 (a) 为其赋予默认值或 (b) 使其可用于自定义(未映射)计算属性。集合导航属性没有合理的替代默认值(空是默认值),并且很少/可以避免将其包含在计算中。

于 2013-07-15T21:41:43.467 回答