我正在尝试使用knockout.js,但我似乎遇到了一个我不知道的javascript怪癖。
<ul data-bind="foreach: someList">
<li data-bind="text: number"></li>
</ul>
function NestedViewModel(number) {
self = this;
self.number = ko.observable(number);
}
function ViewModel() {
self = this;
self.someList = [];
for (i=0;i<10;i++) {
var vm = new NestedViewModel(i);
self.someList.push(vm);
}
}
ko.applyBindings(new ViewModel());
当我运行此代码时,没有任何反应。控制台显示错误:
Uncaught TypeError: Cannot read property 'push' of undefined
当我删除self = this;来自NestedViewModel的行,我用this.number替换self.number,一切正常!我不清楚javascript在这里做了什么......有人对此有解释吗?一个解决方案?
答案 0 :(得分:6)
您需要通过将var
放在它们前面来声明这些变量。在没有声明它们的情况下,您正在尝试写入全局self
,大多数浏览器都不允许您这样做。 (如果不是在浏览器中已经存在全局调用self
,则该代码将成为The Horror of Implicit Globals的牺牲品,并且仍然需要var
- 事实上,它会在稍后发生, i
。)
E.g:
function NestedViewModel(number) {
var self = this;
// ^^^
self.number = ko.observable(number);
}
function ViewModel() {
var self = this;
// ^^^
self.someList = [];
for (var i=0;i<10;i++) {
// ^^^
var vm = new NestedViewModel(i);
self.someList.push(vm);
}
}
ko.applyBindings(new ViewModel());
(请注意,引用代码中不需要self
变量,但我假设您在某些时候使用了闭包,self
变得有用。)
它对self
没有帮助,但您可能需要考虑使用严格模式,这会警告您未声明的i
变量。您可以将"use strict"
放在脚本文件的顶部; more here
答案 1 :(得分:0)
除了@ T.J的回答。你可能也想让数组成为一个可观察的......
self.someList = ko.observableArray([]);