【问题标题】:Knockout / Complex Object Issue淘汰赛/复杂对象问题
【发布时间】:2013-06-11 19:34:39
【问题描述】:

让我先声明一下我昨天下午才开始使用 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,但数组的长度报告为零。

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

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

【问题讨论】:

  • 你能把你的 html 包含在你做数据绑定的地方吗?
  • 这是我正在研究的解决方案的 jsfiddle - jsfiddle.net/djnattyp/Np2BY/4

标签: knockout.js


【解决方案1】:

你应该调用self.Competition().Criteria.push而不是self.Competition().Criteria().push,因为self.Competition().Criteria()会给你原始的普通数组。

【讨论】:

  • 也感谢您的帮助。我不确定我是否理解使用 () 和不使用 () 之间的区别,所以我需要回去做更多的挖掘,看看我是否可以解决它。无论如何,这就是解决我报告的问题的原因。
【解决方案2】:

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

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

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

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

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

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

【讨论】:

  • 感谢您的指导。我认为你说的有些道理。我将不得不慢慢消化剩下的部分。我将另一个回复标记为已接受的答案,因为这最终解决了报告的问题。
猜你喜欢
  • 2012-12-21
  • 2015-03-30
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多