Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone routing with subviews

I'm curious how people deal with a situation like this. I have an application that at a route like "/categories" displays a list of categories. When each category is clicked on, a list of products in that category appears, and the route updates to something like "/categories/1/products". If I navigate some and then click the back button, I should be able to just render the products list view for the previous category, without re-rendering the categories view.

However, I also need to ensure that when I navigate directly to "/categories/2/products" the categories list as well as the products list is rendered.

Basically, it means the router would have to respond differently to back/forward history navigation than to accessing a URL directly. Is there a common solution to this type of problem?

like image 537
clem Avatar asked Jul 13 '12 20:07

clem


1 Answers

Yes, children sections must be called always after parent is created, no matters if it was accessed by direct url or through a Router navigation.

My workaround to this is always have a main View in my applications, and the router always call this Main View. The Router does not have access to other Views. In my Main View I could handle the case where a parent view is created or not.

Example, check how the Router only calls MainView and there I have a method named validateCategories that create the parent View if needed:

var MainView = Backbone.View.extend({
    id : 'mainView',
    categories : null,

    events : {
    },

    initialize : function(){
        _.bindAll(this);
    },

    openSection : function(section){
        switch(section){
            case 'categories':
                this.validateCategories();
                break;
            case 'products':
                this.validateCategories();
                this.categories.open( new ProductsView() );
                break;
        }
    },
    validateCategories : function(){
        if( !this.categories ){
          //we create the parent view only if not yet created
          this.categories = new CategoriesView();
        }
    }
});
var mainView = new MainView();
var RouterClass = Backbone.Router.extend({

  routes : {
    "categories"    : "viewCategories",
    "categories/:id/:section"   : "viewProducts"
  },

  viewCategories : function(path) {
    mainView.openSection( 'categories' );
  },

  viewProducts : function(id, section){
    mainView.model.set({
        productId : id,
        section : section,
    });
    mainView.openSection( 'products' );
  }
});

Also if you are going to start from scratch a new project do not forget to take a look on this extension that help you to organize your Backbone.js Projects: https://github.com/derickbailey/backbone.marionette

like image 53
Daniel Aranda Avatar answered Sep 28 '22 18:09

Daniel Aranda