I received some great feedback on last night's poor man's caching solution in Backbone.js. Before implementing some of those suggestions, I think I need a better mechanism for expressing which month my calendar application is currently displaying.
I think Backbone routes are probably the best way to go.
So first up, I rip out the existing Navigation view, which binds events to next and previous links:
var CalendarNavigation = Backbone.View.extend({
events: {
'a:click': 'preventDefault',
'click .previous': 'handlePrevious',
'click .next': 'handleNext'
},
preventDefault: function(e) { e.preventDefault(); },
handlePrevious: function() {
console.log("[handlePrevious]");
var date = Helpers.previousMonth(appointments.getDate());
draw_calendar(date);
appointments.setDate(date);
},
handleNext: function () {
console.log("[handleNext]");
var date = Helpers.nextMonth(appointments.getDate());
draw_calendar(date);
appointments.setDate(date);
},
render: function() {
this.el.html(
'<div class="previous"><a href="#">previous</a></div>' +
'<div class="next"><a href="#">next</a></div>'
);
this.el.find("a").bind('click', function(e) {e.preventDefault();});
return this;
}
});
In its place I build a route based view, with some dummy values for the next and previous dates: var CalendarNavigation = Backbone.View.extend({
initialize: function(options) {
this.collection = options.collection;
},
template: _.template(
'<div class="previous">' +
'<a href="#month/<%= previous_date %>">previous</a>' +
'</div>' +
'<div class="next">' +
'<a href="#month//<%= next_date %>">next</a>' +
'</div>'
),
render: function() {
$(this.el).html(this.template({
previous_date: "2011-09",
next_date: "2011-11"
}));
return this;
}
});
I will dynamically grab the dates from the collection once I have this hooked together.Loading the page and inspecting the DOM, I see that I am on the right track:
To handle these URLs, I need to set up a router to respond to
#/month/YYYY-DD
formatted URLs. The Backbone router for this should look something like: var Routes = Backbone.Router.extend({
routes: {
"month/:date": "setMonth"
},
setMonth: function(date) {
console.log(date);
}
});
Loading up the page and clicking "next" and "previous", I do see the change in month:Replacing the tracer bullets in
setMonth()
with real code involves only re-drawing the calendar and telling the collection to use the new date: var Routes = Backbone.Router.extend({
routes: {
"month/:date": "setMonth"
},
setMonth: function(date) {
console.log("[setMonth] %s", date);
draw_calendar(date);
appointments.setDate(date);
}
});
And that is all that is needed. After clicking the (still hard-coded) previous and next links several times, I see the one November appointment as expected:And, checking Chrome's Javascript console, I see that my caching is still working, but now with the updated router:
The first time that I request September and November, my poor man's cache results in a cache miss and a subsequent XHR request. After that, however, subsequent requests of those months result in a cache hit and no more XHR requests are necessary.
That will do as a stopping point for tonight. Up tomorrow, I will attempt to adapt this router based filter for a better caching solution.
Day #172
No comments:
Post a Comment