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?
source to share
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 .
source to share