让我先说明我昨天下午才开始与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,但数组的长度将报告为零。
因为我只能中途工作,这告诉我我做错了。我错过了什么?
非常感谢能够引导我朝正确方向前进的人。
答案 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对于您的具体问题的原因是正确的。