self =这个奇怪的行为在嵌套的viewmodel中有knockout

时间:2015-04-27 21:18:48

标签: javascript knockout.js

我正在尝试使用knockout.js,但我似乎遇到了一个我不知道的javascript怪癖。

HTML

<ul data-bind="foreach: someList">
    <li data-bind="text: number"></li>
</ul>

的Javascript

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在这里做了什么......有人对此有解释吗?一个解决方案?

jsFiddle

2 个答案:

答案 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([]);