I'm playing around with Knockout JS, and in this code sample:
var data =
{
allMakes: ko.observableArray([
{ name: "Toyota" },
{ name: "Fiat"}
]),
allModels: ko.observableArray([
{ name: "Corolla", make: "Toyota" },
{ name: "Celica", make: "Toyota" },
{ name: "Avensis", make: "Toyota" },
{ name: "Uno", make: "Fiat" },
{ name: "Bravo", make: "Fiat" }
])
};
var myViewModel =
{
makes : data.allMakes,
models: ko.computed(function() {
if (!myViewModel.selectedMake())
return;
// TODO: filter models by selected make
}),
selectedModel: ko.observable(""),
selectedMake: ko.observable("")
};
/* Uncomment it to work
myViewModel.models = ko.computed(function() {
if (!myViewModel.selectedMake())
return;
// TODO: filter models by selected make
});
*/
ko.applyBindings(myViewModel);
http://jsbin.com/upaxum/8/edit
we can see that I try to access myViewModel variable inside models: ko.computed . However myViewModel is undefined when this computed observable runs. And I don't know why?
However if I create models computed observable in next statement, myViewModel variable is defined. Why is that?
EDIT: one of the answers suggests that I'm accessing the object before it is created. So how come that this code snippet works?
var myViewModel =
{
myFnk : function()
{
console.log(myViewModel);
}
};
myViewModel.myFnk();
This is something that trips me up from time to time. ko.computed executes once as soon as it is defined. It does this so that it knows which variables it needs to subscribe to watch for changes.
So in this code
models: ko.computed(function() {
if (!myViewModel.selectedMake())
return;
// TODO: filter models by selected make
})
myViewModel is accessed before it has been assigned to in the var myViewModel =
line because the ko.computed is executing the function as soon as it is defined.
In your second example you are executing the function AFTER myViewModel has been defined so that is why it works. If you wanted to replicate this in your first example you might do something like:
var myViewModel =
{
makes : data.allMakes,
selectedModel: ko.observable(""),
selectedMake: ko.observable("")
};
myViewModel.models = ko.computed(function() {
if (!myViewModel.selectedMake())
return;
// TODO: filter models by selected make
});