I'm a newbie to JavaScript, and I'm not very sure about the following legacy knockout and JS code which is being used in my app:
file1.js:
var FbPicturesObj = {
fbPicturesVM: new FbPicturesVM(),
initialize: function () {
ko.applyBindings(FbPicturesObj.fbPicturesVM, $("#fb-albums")[0]);
ko.applyBindings(FbPicturesObj.fbPicturesVM, $("#fb-album-photos")[0]);
},
Reset: function Reset() {
FbPicturesObj.fbPicturesVM.albums([]);
FbPicturesObj.fbPicturesVM.photos([]);
}
}
file2.js:
function FbPicturesVM() {
...... some code ....
}
My question are:
FbPicturesObj.fbPicturesVM
will create a new instance of fbPicturesVM in memory?ko.applyBindings
calls are written correctly? (in terms of code optimization)Thanks a lot.
File1.js
contains a definition of a JavaScript object, more exactly a "literal object creation".
Inside it, each propertyName: value
pair declares an initializes a new property, so that code is run only once, when creating the object. For example fbPicturesVM: new FbPicturesVM()
Properties of JavaScript objects can be functions, like this: initialize: function () {...},
. In this case, whenever you run FbPicturesObj .initialize
this function will be run.
The calls to ko.applyBindings
are correct. This method expects the viewmodel object and an optional DOM element as the second parameter. A jQuery expression is (not exactly) an array of selected DOM elements, so this $("#fb-album-photos")[0]
extracts the first DOM element of the jQuery expression, as needed by ko.applyBindings
.
NOTE: as you suspect, the way of defining the model is not the best possible, to say the least. You can use the Revealing Module Pattern, which makes things much easier.
In few words:
var vm = (function() { // declare a function
// create variables and functions
var name = ko.observable();
var age = ko.observable();
var _privateVar = 'Yuhu'; // won't be revealed
var incAge = function() {
age = age + 1;
};
// reveal only what you want, by returning it in an object
return {
name: name,
age: age,
incAge: incAge
// note that _privateVar is not exposed, but could be
}
})(); // This invokes the function, so that it return the model
NOTE the pattern Immediately-Invoked Function Expression (IIFE).
var value = (function() {/*return something*/})();
This pattern defines an anonymous function, that returns something. The ()
at the end runs it, so that the value is returned, and stored in value
;
I recommend this patter because it's extremely easy to use and little error prone. Classical prototypal inheritance, constructor, and things like that are much harder to work with.
You can easyly convert this in a view model factory (something similar to a constructor, but not eactly a js constructor) by removing the invocation - ()
at the end - and storing the funcion definition, so that you can call it repeatedly.
var factory = function() {/*return something*/};
var vm1 = factory();
var vm2 = factory();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With