Backbone: Best way to prevent routes (and url change)

342 views Asked by At

I have an editor view and if there are unsaved changed I am prompting on window closes and also on backbone routes.

Problem is that Backbone.Router.execute runs after the url change and so I am trying to implement the most reliable and elegant way of preventing the url change.

In the example below clicking the "About" route will prevent the route callback and then rewind the url change - it seems less than ideal that I have to use window.history.back() (because it creates a history entry).

Can you think of a better way? I know a jQuery on-click can catch the event before url change but I'm not sure how to nicely integrate that with a Backbone.Router. Thanks.

var HomeView = Backbone.View.extend({
 template: '<h1>Home</h1>',
 initialize: function () {
  this.render();
 },
 render: function () {
  this.$el.html(this.template);
 }
});

var AboutView = Backbone.View.extend({
 template: '<h1>About</h1>',
 initialize: function () {
  this.render();
 },
 render: function () {
  this.$el.html(this.template);
 }
});

var ContactView = Backbone.View.extend({
 template: '<h1>Contact</h1>',
 initialize: function () {
  this.render();
 },
 render: function () {
  this.$el.html(this.template);
 }
});

var AppRouter = Backbone.Router.extend({
 routes: {          
  '': 'homeRoute',
  'home': 'homeRoute',
  'about': 'aboutRoute',
  'contact': 'contactRoute'
 },
 execute: function(callback, args, name) {
  if (window.location.hash === '#/about') {
   window.history.back();
   return false;
  }
  if (callback) {
   callback.apply(this, args);
  }
 },
 homeRoute: function () {
  var homeView = new HomeView();          
  $("#content").html(homeView.el);
 },
 aboutRoute: function () {
  var aboutView = new AboutView();
  $("#content").html(aboutView.el);
 },
 contactRoute: function () {
  var contactView = new ContactView();
  $("#content").html(contactView.el);
 }
});

var appRouter = new AppRouter();
Backbone.history.start();
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="http://underscorejs.org/underscore.js"></script>
<script src="http://backbonejs.org/backbone.js"></script>

<div id="navigation">
    <a href="#/home">Home</a>
    <a href="#/about">About</a> 
    <a href="#/contact">Contact</a> 
</div>    
<div id="content"></div>

The only thing I can think of is listening to clicks and doing things with jQuery, or saving the last hash and doing window.history.replaceState(undefined, undefined, "#last_hash_value").

0

There are 0 answers