2
votes

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.

1
Any reason you are using an extra array (breadcrumbs) that you then pass on to a method on the CollectionView instead of just adding a new model to the collection itself? Your CollectionView should just listenTo the collection changing and re-render.christian314159
I'm new to Backbone. I don't have any specific reason to add the extra array, may be I understand the things wrongly. I just tried what you mentioned here, but didn't work, may be I have to do some more modifications. Am I following the correct coding structure? Do you have any working sample for it?San

1 Answers

1
votes

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' });