Technically you could do that, but it is not the way Knockout is meant to be used. For example, let's say our viewmodel has one <select>
and one text <input>
binding. Using the private vars to hold the actual values, means we need a writable computed
observable to update it, because Knockout only binds properties to your view, not private vars.
function appWithPrivateVars() {
var selectedItem = ko.observable('Option 3'), //our private vars
textVal = ko.observable('Haha');
this.selected = ko.computed({
read: function() { return selectedItem(); },
write: function(value) { /* add validation code here */ selectedItem(value); }
});
this.textVal = ko.computed({
read: function() { return textVal(); },
write: function(value) { /* add validation code here */ textVal(value); }
});
this.listItems = ['Option 1','Option 2','Option 3'];
this.get = function() { return selectedItem(); }; //getter
}
Now compare with the code needed for the same viewmodel without caring about private vars (also notice you don't need an explicit getter/setter) :
function appWithProperties() {
var self = this;
this.textVal = ko.observable('Haha');
// example of computed
this.textValInput = ko.computed({
read: function() { return self.textVal(); },
write: function(value) { /* add validation code here */ textVal(value); }
this.selected = ko.observable('Option 3');
this.listItems = ['Option 1','Option 2','Option 3'];
}
The thing is you don't need to 'protect' your otherwise accessible model properties because if they are not bound to the view, they will not be able to be modified. Furthermore, you will get yourself in trouble if you use var
's at the moment you want to easily serialize your data to JSON with the ko.toJSON
function (unless you're willing to rewrite an entire parsing function). Compare the outputs of ko.toJSON
for both viewmodels:
Sample data for appWithPrivateVars
// no private vars included, eg. 'selectedItem'
{"selected":"Option 1", // computed prop; not what we need
"textVal":"Haha",
"listItems":["Option 1","Option 2","Option 3"]}
See how the 'actual' values are not included in the mapping (which is logical because ko.toJSON
doesn't have access to them). Now check out the JSON output for appWithProperties
:
{"textVal":"Haha", // actual value
"textValInput: "Haha", // value filter
"selected":"Option 1",
"listItems":["Option 1","Option 2","Option 3"]
}
Check out the fiddle