My backbone.js has three views:
I'm using backbone.js router to navigate between these views. The user flows in the app go 1<-->2, 2<-->3 and 3 --> 1. The user can navigate back and forth using browser back and forward buttons, which is wanted behavior. Deep linking to any item works also.
The problem is that I want to keep the history clean. Here's an example usage flow:
Another example:
Any ideas on how to implement this in a clean way?
There is no way to implement the first example that you provided. You cannot implement the first example because there is no way to "delete" the browser history using Javascript.
There is no way to clear the session history or to disable the back/forward navigation from unprivileged code. The closest available solution is the location.replace() method, which replaces the current item of the session history with the provided URL.
- https://developer.mozilla.org/en/DOM/window.history
At best you can prevent the current page from being added to the browser history by using window.location.replace
or window.history.replaceState
. Backbone.js provides a convenient way of doing this by calling router.navigate(fragment, [options])
on your router object and specifying {replace: true}
in the options.
Instead of relying on different routes to determine which view to display, I would try instead writing a master view which could handle showing/hiding the specific views.
Ok, entering hacky territory...
Since it seems that the "Category List" page is the page where history should be "reset", the solution I have posted attempts to solve both use cases you have mentioned. The code keeps track of a historyState
variable, which represents when the "category-list" page is visitied as well as the other pages visited after it.
// in your application init...
$(function(){
window.historyState = -1;
router = new Backbone.Router({
routes: {
"category-list": category-list,
"category": category,
"item": item
}
category-list: function(){
historyState = 0;
},
category: function(){
if(historyState >= 0)
historyState++;
},
item: function(){
if(historyState >= 0)
historyState++;
}
});
});
historyState
is -1
- we have not yet visited the "category-list" page.historyState
is 0
- we are currently on the "category-list" page.historyState
is greater 0
- number of pages visited since viewed "category-list" page.Now anytime a link is used to navigate to the "category-list" page, make sure it calls the following method to handle the appropriate navigation.
function routeToCategoryList(){
if( historyState > 0 ){
// 'category-list' already exists in our history route to that page.
window.history.go((historyState * -1));
} else {
// otherwise, don't store an entry for the current page we are on.
router.navigate("/category-list", {trigger: true, replace: true});
}
}
If the 'category-list' page has already been visited go back in history the appropriate number of entries (this unfortunately keeps the other pages in the history, so you can still go forward to them). Otherwise if the 'category-list' page hasn't been visited yet navigate to it and be sure not to add the current page to the history.
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