Reputation: 2785
I'm looking for feedback, suggestions on how to structure my java scripts better. I've made an attempt to move js code into their own files. It works but I wonder if this is the preferred way when it comes to scripts like the sample below? Is the revealing prototype pattern overkill, or not a good option for other reasons?
Portalen.Archive = function() {
};
Portalen.Archive.prototype = function () {
var options = {
minDate: new Date(2012, 0, 1),
changeMonth: true,
changeYear: true
};
var start = function () {
$("#StartDate").datepicker(options);
$("#EndDate").datepicker(options);
$("#searchButton").on("click", function() {
search();
});
};
var search = function() {
$.ajax({
url: "/Archive/Index",
type: "post",
data: $("#searchForm").serialize(),
success: function (response) {
$("#resultContainer").html(response);
}
});
};
return {
start: start
};
}();
And in the view I use it like this
<script type="text/javascript" src="~/Scripts/app/portalen-archive.js"></script>
<script type="text/javascript">
$(function () {
var s = new Portalen.Archive();
s.start();
})
</script>
Upvotes: 2
Views: 113
Reputation: 20453
I use this way sometimes:
/* defined in ~/Scripts/app/portalen.js */
var Portalen = {
Archive: '',
AnotherClass: ''
}
/* defined in ~/Scripts/app/portalen-archive.js */
Portalen.Archive = function(options){
this.options = {
someSettings: 'default',
anotherOneOption: [],
datePickerSettings: {
minDate: new Date(2012, 0, 1),
changeMonth: true,
changeYear: true
}
}
/* You can overwrite these settings (this.options) when creating an instance */
$.extend(this.options, options)
/* auto init an instance.. but you can remove it and call init when & where you want after creating an instance of Portalen.Archive */
this.init();
}
Portalen.Archive.prototype = {
init: function(){
var self = this;
console.log('initialize');
self._bindEvents();
},
search: function(){
$.ajax({
url: "/Archive/Index",
type: "post",
data: $("#searchForm").serialize(),
success: function (response) {
$("#resultContainer").html(response);
}
});
},
_bindEvents: function(){
var self = this;
$("#StartDate").datepicker(self.options.datePickerSettings);
$("#EndDate").datepicker(self.options.datePickerSettings);
$("#searchButton").on("click", function() {
self.search();
});
}
}
And you can create instance
<script type="text/javascript" src="~/Scripts/app/portalen.js"></script>
<script type="text/javascript" src="~/Scripts/app/portalen-archive.js"></script>
<script type="text/javascript" src="~/Scripts/app/portalen-another-class.js"></script>
<script>
$(function(){
/* For now it will automaticly call init method.. */
var archive = new Portalen.Archive({
/* you can overwrite any optioin */
someSettings: 'overwrite this option'
});
});
</script>
I will appreciate any suggests to improve this pattern :))
Upvotes: 1
Reputation: 7295
JavaScript is not Java, where all entities should be represented with classes.
Therefore we're using classes/prototypes in JavaScript only when we need to create multiple objects of current type.
So creating of class here is not necessary in my opinion. But though you can use regular JavaScript object as namespace.
Also I'd name this method rather init
than start
, but it's up to you of course.
In module:
var Portalen = (function($, window, app) {
app.Archive = {} || app.Archive;
var options = app.Archive.options = {
minDate: new Date(2012, 0, 1),
changeMonth: true,
changeYear: true
};
var search = app.search = function() {
$.ajax({
url: "/Archive/Index",
type: "post",
data: $("#searchForm").serialize(),
success: function (response) {
$("#resultContainer").html(response);
}
});
};
app.Archive.init = function() {
app.initDatePickers();
app.initEventHandlers();
};
app.initDatePickers = function() {
$("#StartDate").datepicker(options); // or app.options
$("#EndDate").datepicker(options);
};
app.initEventHandlers = function() {
$("#searchButton").on("click", app.search);
};
return app;
})(jQuery, window, Portalen || {});
Somewhere else:
$(function() {
Portalen.Archive.init();
});
Additionaly I want to suggest you to take a look to Require.js which will allow you to organize your JavaScript modules in convenient way.
Upvotes: 1
Reputation: 2941
I recently started using require.js. It's making use of module
pattern. You can define modules and later import them when needed and express dependencies in way of somewhat python-style imports.
Additional upside in this case is that you don't have to abuse "class" creation to wrap once-used code to prevent it from polluting global namespace. You can just use module for this, which is cleaner and more expressive. You can read about objectives of module pattern here. And require.js makes module pattern simple to implement while giving You additional features like AMD
Upvotes: 3