1

让我先声明一下我昨天下午才开始使用 Knockout 库,所以这很可能是这个问题的一个因素。

在进入代码之前,我正在尝试创建一个模型,该模型包含一个 Competition 对象,该对象具有 Name 属性和 Criteria 属性,该属性是 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;
}

在视图模型中,我有一个 Competition 属性,设置如下:

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,但数组的长度报告为零。

由于我只能半途而废,这告诉我我做错了什么。我错过了什么?

非常感谢任何可以引导我朝着正确方向前进的人。

4

2 回答 2

2

你应该打电话self.Competition().Criteria.push而不是self.Competition().Criteria().push,因为self.Competition().Criteria()会给你原来的普通数组。

于 2013-06-11T20:00:43.270 回答
2

首先,并非所有事物都需要是可观察的。实际上,只有在您确实需要该功能时,事物才应该是可观察的。构造、初始化和更新 observables 涉及大量开销。

你还没有展示你的视图模型(你注册的东西ko.applyBindings),但通常,你的视图模型只是你正在与之交互的东西,而不是一些抽象。换句话说,如果您的视图以“竞争”的概念为中心,那么Competition它本身就是您的页面视图模型。

不过,不要创建对象的可观察对象。Knockout 无法检测到对象Competition的变化,只能检测到整个对象的变化,即您在self.Competitionobservable中存储了一个全新的实例。因此,只需将其视为视图模型上的简单 JS var:

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

然后,如果您想在其中引用一个可观察对象,您只需像在 JS: 中一样将其链接起来self.Competition.SomeObservable()

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

于 2013-06-11T20:00:57.083 回答