Search code examples
backbone.jsmarionette

Breadcrumb with Backbone.Marionette


I'm trying to implement breadcrumb using Marionette.CollectionView and Marionette.ItemView. I want to add breadcrumbs to the list from any part of the module.

Here is the module which I wrote:

App.module("BreadcrumbModule", function(BreadcrumbModule){
var instance;

var Breadcrumb = Backbone.Model.extend({
    defaults:{
        link        : '',
        name        : ''            
    } 
});

BreadcrumbModule.BreadcrumbList = Backbone.Collection.extend({
    model : Breadcrumb
});

var BreadcrumbView = Marionette.ItemView.extend({
    tagName : 'li',

    render : function() {
        var liData = '';
        if(this.model.get('link') == '#') {
            liData = 'You are here: ';
        } else {
            liData = '<a href="#' + this.model.get('link') + '" class="tabSection">' + this.model.get('name') + '</a>';
        }

        $(this.el).html(liData);
        return this;
    }
});

BreadcrumbModule.BreadcrumbListView = Marionette.CollectionView.extend({
    tagName: "ul",
    id: "Breadcrumb",                

    itemView: BreadcrumbView,        

    initialize : function() {                       
        this.collection = new BreadcrumbModule.BreadcrumbList();                   

        this.collection.bind('add', this.appendBreadcrumb);       

        //this.collection.add({link: '#', name: 'You are here : '});
        this.listenTo(this.collection, "add", this.appendBreadcrumb);   
    },

    addBradcrumb: function(breadcrumbList){

        breadcrumbList.forEach(function(breadcrumb) {
            //console.log(breadcrumb);
            this.collection.add(breadcrumb);
        }, this);
    },      

    appendBreadcrumb: function(breadcrumb) {
        var breadcrumbView = new BreadcrumbView({
            model : breadcrumb
        });            

        $(this.el).append(breadcrumbView.render().el);
    }
});

// Singleton
BreadcrumbModule.getInstance = function() {
    if(!BreadcrumbModule.instance) {
        instance = new BreadcrumbModule.BreadcrumbListView();
    } 

    return instance;        
}        

});

My plan to access this module as follows:

 //var breadcrumbs = []; 
 //breadcrumbs.push({link: 'book', name: 'Book'});

 //var breadcrumbListView = App.BreadcrumbModule.getInstance();

 var breadcrumb = new App.BreadcrumbModule.Breadcrumb({link: '#', name: 'You are here: '});
 var breadcrumbList = new App.BreadcrumbModule.BreadcrumbList();  
        breadcrumbList.add(breadcrumb);
 breadcrumbListView.addBradcrumb(breadcrumbs);

I can see the default one is showing("You are here:") and the 'collection' is growing when I add new breadcrumbs but its not reflecting in the view.

What could be the reason?

How can I fix it?

Thank you!

//San.


Solution

  • I've written a simple example on JSFiddle: http://jsfiddle.net/zaSvT/ The main differences to your code are these:

    The CollectionView is listening to its collection and re-renders every time the collection changes (e.g.

    var BreadcrumbListView = Marionette.CollectionView.extend({
            el         : '#breadcrumbs',
            childView  : BreadcrumbItemView,
            initialize : function(){
                this.listenTo(this.collection, 'change', this.render );
                this.render();
            }
        });
    

    And here I just instantiate it with a new collection (1 dummy item to start with):

    var breadcrumbCollection = new Backbone.Collection([{ name : 'foo', url : 'foo' }]);
    
    var breadcrumbView = new BreadcrumbListView({
        collection : breadcrumbCollection
    });
    

    When I add a new item to the collection it will automatically appear:

    breadcrumbCollection.add({ name : 'foo', url : 'bar' });