Encapsulate javascript code in a global object for clearer code
I am trying to get things working using jQuery and jQueryUI's datepicker, inline mode.
I would like to put all my开发者_如何学Go code in a global object, and use it for datepicker init function (beforeShowDay, changeMonthYear). I also have a few utility functions.
I am stuck because I don't really know how to proceed.
I have read quite a few articles, tutorials, stackoverflow threads - especially onthis
scope, etc., but now I don't know where to start!
This is what I have so far:
var Calendar = (function() {
var obj = this;
var calendar = {
datescache: [],
bsd: function (date) {
var offset = this.formatNum(date.getMonth()+1)+'-'+this.formatNum(date.getDate());
if (thedate[offset] != undefined) {
return [true, 'bold', thedate[offset] + ' événement(s)'];
} else {
return [true];
}
},
formatNum: function (i) {return ('0'+i).slice(-2);},
getEventsForDate: function(year, month, inst) {
var date = this.datescache;
if (this.datescache[month] === undefined) {
console.warn('uncached: '+month);
$.ajax({
url: '/event/get-event-count/year/'+year+'/month/'+month+'/format/json',
success: function (resp) {
date[month] = resp.events;
},
async: false
});
}
console.log('return: '+month);
return date[month];
}
}
return calendar;
})();
$('#calendar').datepicker({
dateFormat: "dd\/mm\/yy",
showOtherMonths: true,
selectOtherMonths: true,
beforeShowDay: Calendar.bsd,
onChangeMonthYear: Calendar.getEventsForDate,
});
Of course I have an error at the line:
var offset = this.formatNum(date.getMonth()+1)+'-'+this.formatNum(date.getDate());
because this
refers to the datepicker object, as we are in a the callback function beforeShowDay
that takes care passing the datepicker instance to the function as this
.
But I need this
to refer to my utility functions, such as formatNum
.
- Where should I start ?
- is it better to try to extend the
datepicker
object (not tried yet) ?
Thanks in advance for your help !
EDIT 1
OK, with some more readings and first answer, I managed to get something to work:
var Calendar = (function() {
var calendar = function() {
var self = this;
this.datescache = [];
this.bsd = function (date) {
[[... I use for instance self.datescache ... ]]
}
[[...]]
};
return new calendar();
})();
This seems to work fine.
- Is the global encapsulation still needed ?
Thanks again !
For manipulation this
in callback and other functions there are a few options.
Rather then calling this
inside the function you can call an alias like that
or self
. In your case the variable obj = this
is already an alias so you can call obj.formatNum
The other option is Function.bind
which allows you to do this:
foo : (function() {
...
}).bind(obj),
...
Note that Function.bind
is an ES5 thing. You can use _.bind
or _.bindAll
from underscorejs instead.
Another option to get the this
scope to work is doing this
beforeShowDay: function() {
Calendar.bsd();
},
onChangeMonthYear: function() {
Calendar.getEventsForDate();
},
The difference here is rather then passing along a function (which when invoked will be invoked with a different this
object) your passing along a function that invokes your function ON your own Calendar object thus forcing this
to be Calendar
.
See:
var f = function() { console.log(this); }
var a = {
b: f
};
var c = {}
c.d = a.b;
c.e = function() {
a.b();
};
f(); // window
a.b(); // a
c.d(); // c
c.e(); // calls a.b(); so a
this
scope is whatever object you call the method on.
精彩评论