domingo, 18 de outubro de 2015

Routing in Backbone: to trigger or not to trigger

One of most prominent advices regarding routing in Backbone is to not use the Router to switch states after the application is loaded. As consequence, the usage of hyperlinks or {trigger: true} option in Router.navigate are discouraged. This recommendation is in both Addy Osmani and David Sulc books. For reference, David Sulc's routing chapter is available as a free sample.

Given such strong statements, it would be expected that this practice should be one of corner stones for well designed Backbone applications. But what to say when two of better structured Backbone examples available use the other way around? Both Marionette Wires and Gistbook uses the Router to handle state. In a broader scope, the major web frameworks / libraries use the URL to manage application state. It's something to reason about.

In the Marionette project i'm working, i follow the general advice and uses the router only as an entry point. See below for the general architecture.

As a side note, IMHO the Marionette.AppRouter adds very little to the default Router to justify its existence.


//a service to handle navigation (using pub/sub)

var Radio = require('backbone.radio');

var PageManager = Marionette.Object.extend({
 initialize: function () {
  this.navigationChannel = Radio.channel('navigation');
  this.navigationChannel.reply('showPage', this.showPage, this);
 },
        //page configuration how to load a view
 pages: {
  newbuy: {
   path: 'newbuy'
  },
  ownedstock: {
   path: function(id) {
     return 'ownedstock/' + id
   },
   options: function(id) {

   }
  }
 },
 showPage: function(name) {
  //..
 }
});


//router.js
var NavChannel = require('backbone.radio').channel('navigation');

var Router = Backbone.Router.extend({
 routes: {
  'newbuy': 'showNewBuy',
  'ownedstock/:id': 'showOwnedStock'
 },
 showNewBuy: function() {
  NavChannel.request('showPage', 'newbuy');
 },
 showOwnedStock: function (id) {
  NavChannel.request('showPage', 'ownedstock', id);
 }
});

//navigation inside app

  onAddBuyClick: function (e) {
    e.preventDefault();
    Radio.channel('navigation').request('showPage', 'newbuy');
  }

//the application is responsible for show the view in the proper region
var Application = Marionette.Application.extend({
  initialize: function () {
    this.router = new Router();
    this.rootView = new RootView({});
    this.pages = new PageManager();
    this.listenTo(this.pages, 'show:page', this.onShowPage);
  },
  onShowPage: function (view) {
    this.rootView.showChildView('content', view);
  },
  onStart: function() {
    console.log('app start');
    Backbone.history.start();
  }
});



Nenhum comentário:

Postar um comentário