淘汰/复杂对象问题

时间:2013-06-11 19:34:40

标签: knockout.js

让我先说明我昨天下午才开始与Knockout图书馆合作,所以这很可能是这个问题的一个因素。

在我进入代码之前,我正在尝试创建一个模型,该模型具有一个具有Name属性和Criteria属性的Crit对象,该属性是Criterion对象的集合。 Criterion对象具有PrimaryDescription和SecondaryDescription属性。

这是我到目前为止所做的:

function Competition(name, criteria)
{
  var self = null;

  self = this;

  self.Name = ko.observable(name);
  self.Criteria = criteria;

  return;
}

function Criterion(id, primaryDescription, secondaryDescription)
{
  var self = null;

  self = this;

  self.Id = id;
  self.PrimaryDescription = ko.observable(primaryDescription);
  self.SecondaryDescription = ko.observable(secondaryDescription);

  return;
}

在视图模型中,我有一个像这样设置的竞赛属性:

self.Competition = ko.observable(new Competition('Competition 1', ko.observableArray([new Criterion(-1, 'Criterion 1', 'Criterion 1'), new Criterion(-1, 'Criterion 2', 'Criterion 2')])));

当页面加载时,绑定到Competition()。Criteria()按预期工作。

在视图模型中,我添加了以下内容:

self.addCriterion =
  function ()
  {
    self.Competition().Criteria().push(new Criterion(-1, '???', '???'));

    alert(self.Competition().Criteria().length);

    return;
  }

当我调用此方法时,新元素将添加到数组中,并准确反映数组长度。但是,绑定不会更新。我搞砸了一下,将竞争模型部分的一行从“self.Criteria = criteria”改为“self.Criteria = ko.observableArray(criteria)”。当我执行此操作并调用addCriterion方法时,新元素将添加到数组中,绑定将更新UI,但数组的长度将报告为零。

因为我只能中途工作,这告诉我我做错了。我错过了什么?

非常感谢能够引导我朝正确方向前进的人。

2 个答案:

答案 0 :(得分:2)

您应该拨打self.Competition().Criteria.push而不是self.Competition().Criteria().push,因为self.Competition().Criteria()会为您提供原始普通数组。

答案 1 :(得分:2)

首先,并非一切都需要是可观察的。事实上,如果你真的需要这个功能,事物应该只是一个可观察的东西。构建,初始化和更新可观察对象涉及大量开销。

您尚未展示您的视图模型(您使用ko.applyBindings注册的内容),但通常情况下,您的视图模型将只是您要​​与之交互的内容,而不是某些抽象。换句话说,如果您的观点以“竞争”的概念为中心,那么Competition本身就是您的页面视图模型。

然而,不要创建对象的可观察对象。 Knockout无法检测对象内的更改,只会更改整个对象,即您在Competition可观察对象中存储全新的self.Competition实例。因此,只需将其视为视图模型上的简单JS var:

self.Competition = new Competition( ... );

然后,如果你想在其中引用一个observable,你只需在JS中正常链接它:self.Competition.SomeObservable()

@jaux对于您的具体问题的原因是正确的。