Reputation: 2048
I'm using a Backbone Router with Backbone.history.start({pushState: true, root: "/"});
and I'm loading sections of pages through AJAX and use Backbone.history.navigate(url, true);
to make sure the url shown by the browser points to the corresponding section.
For instance, I load a page with the relative url "/username/profile", then load a section on that page ('Favorite Books') by clicking on a tab and triggering an AJAX request, and then change the url to "/username/favorite_book".
The problem is that if I go back (with the Back button) to a previous section from the one loaded through ajax, the page content does not change even though the url changes.
I have seen previous posts talking about Ajax Browser History, but I would like to know what should I do in the context of Backbone? I could not find a clear explanation of the issue and how to solve it.
To be precise, what should I add to the function I trigger when clicking on the tab of a section to be loaded with ajax? My aim is to change the URL and the page (go back to state before AJAX request) when using the Back button. I'm currently doing as follows:
RenderSection: function(event) {
var data = '';
var url = $(event.currentTarget).attr("href");
$.post(url, data, function(data){
$(".ajax_section").html(data);
var protocol = this.protocol + '//';
// Ensure the protocol is not part of URL, meaning its relative.
if (url && url.slice(protocol.length) !== protocol) {
Backbone.history.navigate(url, true);
}
});
return false;
},
Upvotes: 1
Views: 2466
Reputation: 2048
Turns out I was not using Backbone correctly. Here is what I ended up using and it works great!
In my Backbone View, I created 2 methods: the first is triggered when a link (an anchor) with class="ajax_enabled" is clicked, while the second is triggered by a Backbone Events trigger included in the Router's action. The Backbone View methods look as follows:
events: {
'click a.ajax_enabled': 'NavigateToUrl'
}
initialize: function() {
EventAggregator.on("render:route", this.RenderAjax, this);
},
NavigateToUrl: function(event) {
var url = $(event.currentTarget).attr("href");
var protocol = this.protocol + '//';
// Ensure the protocol is not part of URL, meaning its relative.
if (url && url.slice(protocol.length) !== protocol) {
Backbone.history.navigate(url, true);
}
return false;
},
RenderAjax: function(route) {
var data = '';
var url = window.location.pathname + window.location.search;
$.post(url, data, function(data){
$(".ajax_section").html(data);
});
}
My Backbone Router handles the call from Backbone.history.navigate(url, true);
and triggers the event to update the view through the default action, as follows:
window.EventAggregator = _.extend({}, Backbone.Events);
var Router = Backbone.Router.extend({
initialize: function(options) {
var router = this;
Backbone.history.start({pushState: true, root: "/", silent: true});
},
routes: {
'' : 'defaultAction',
'*route': 'defaultAction'
},
defaultAction: function(route) {
if(typeof(route)==='undefined') {
route = '';
}
EventAggregator.trigger("render:route", route);
}
});
return Router;
For reference, I found this other answer helpful, about using events to trigger methods in the View from the Router.
Upvotes: 2