Self = this is strange behavior in nested viewmodel with knockout

I am trying to deal with knockout.js but I seem to be running into a javascript quirck that I am not aware of.

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());

      

When I run this code, nothing happens. The console displays an error message:

Uncaught TypeError: Cannot read property 'push' of undefined

      

When I remove self = this; line from NestedViewModel and I replace self.number with this.number everything works fine! I have no idea what the javascript is doing under the hood here ... Anyone have an explanation? And the solution?

jsFiddle

+3


source to share


2 answers


You need to declare these variables by putting var

in front of them. By not declaring them, you are trying to write a global one self

, which most browsers won't let you do. (If it weren't for the fact that browsers already have a global called self

, this code would fall prey to the Horror of Implicit Globals and would still want to var

- in fact, that happens later, p i

.)

eg:.

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());

      




(Keep in mind that there is no need for a variable self

in the quoted code, but I am assuming you are using a closure at some point, but it self

will become useful then.)




It wouldn't help with self

, but you might need to use strict mode, which would alert you to an undeclared variable i

. You do this by placing "use strict"

a script at the beginning of the file; more details here .

+6


source


In addition to @TJ's answer, you might want to make the array visible too ...



self.someList = ko.observableArray([]);

      

0


source







All Articles