Monday, November 28, 2011

Browser History and Backbone.js Redirection

‹prev | My Chain | next›

Up tonight a little bit flipping with Backbone.js routes. In the upcoming Recipes with Backbone (which is due in lesS THAN TWO DAYS11!!!!! It's OK. I'm OK. Just breathe…), we have a recipe for router redirection which ends up a little confused.

Specifically, we start the recipe discussing the benefits of server-side redirection, which does not contribute to browser history, and comparing that to clien-side redirection, which does. We somewhat imply that Backbone redirection can achieve similar results, but then never go back to verify this claim (or even mention it again).

So my goal tonight is to either generate some backing material for said recipe or remove that claim (the recipe is already pretty awesome without it). For this, I will not be using my Calendar application. Rather, I think that a smaller, simple Backbone application will suffice.

So I trigger next /previous events in a simple view. With those events in the router, I navigate forward / backward:
  var Routes = Backbone.Router.extend({
    initialize: function(options) {
      this.paginator = options.paginator;
      _.bindAll(this, 'next', 'previous');
      paginator.bind('next', this.next);
      paginator.bind('previous', this.previous);
    }
What I find when I do this is that after clicking next twice I am on page 2:


But clicking the back button leaves me stuck on page 2 — it won't navigate me back.

If I add manual links:
    <h1>Router Redirection</h1>
    <div id="results">testing</div>
    <div id="paginator"></div>
    <div id='manual'>
      <a href='#previous'>Previous</a>
      <a href='#next'>Next</a>
    <div>
...And try visiting the routes directly, I am again able to get to page 2:


So that I am not stuck on the /appointments/#next resource, I manually reset the current URL, effectively redirecting, with the following router method:
    next: function() {
      console.log("[next]");
      this.paginator.move(1).render();
      Backbone.history.navigate("");
    },
But now, when I click the back button, and I am taken back to the next resource, which send me on to page 3!


Ugh. I still do not know that I have a definitive answer to how client-side redirection might work in Backbone. All I know right now is that I cannot make it work. So I suppose I am leaning toward removing that section from the recipe. Still, I will sleep on it for now. Maybe I can come up with something tomorrow.


Day #219

2 comments:

  1. I think the answer is in your statement "So that I am not stuck on the /appointments/#next resource..."

    "Next" is not a resource/location, so it shouldn't be a route. The routes should specify identifiers and the next/prev links should be updated each time a route is navigated to. Doing so keeps the back button behavior intact.

    ReplyDelete
  2. @Matt Yah, I think you're ultimately right. What would be a 302 in a server-side app, should be a view event in a BB app. If multiple things want to move to the "next" element, they can each trigger a "next" event.

    Hrm... only trouble with that is that the router listening for the "next" event would have to subscribe to all possible views that might generate that event...

    ReplyDelete