The problem is the way in which you're creating your view model. The view model shuld be self-contained, including the functions that operate on it. It should be something like this:
var ViewModel = function() {
var self = this;
self.type = ko.observable();
self.name = ko.observable();
self.content = ko.observable();
self.type.subscribe(function(newVal) {
// here you have access to all the viewmodel properties through self
});
return self;
};
This is a constructor using the var self=this;
pattern.To use the view model you need to instantiate it, i.e. var vm = new ViewModel()
. (You can omit the new
).
Of course, you can also define a function, and bind it to self
, or receive a callback in the constructor, and bind it to self
. In that case, the function implementation will have the view model accesible via this
, and not self, which will be undefined inside the function body.
var doSomethignWithVm = function(newVal) {
// acces viewmodel via this
// you can also use newVal
};
You modify the constructor to receive this as a callback:
var ViewModel = function(doSomethingCallback) {
self.type.subscribe(callback.bind(self));
};
This pattern doesn't make much sense because your callback is supposed to have knowledge of your view model. In that case it makes more sense to include the subscription functionality directly inside the model.
EDIT
Note: as I've mentioned in a comment to Joel Ramos Michaliszen's answer, both of this codes are equivalent:
self.type.subscribe(callback.bind(self));
self.type.subscribe(callback.bind, self);
You can check that by seeing the source code of subscribable
in knockout's gitbhub, in the file knockout/src/subscribales/subscribable.js
. If you look for subscribe implementation you'll see this:
subscribe: function (callback, callbackTarget, event) {
// ...
boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback;
I.e. if you provide a second argument, it's used tob bind the function passed in the firt argument to it.