Jaime Rivera
Jaime Rivera

Reputation: 1406

After Render Event on CompositeView with Backbone.Marionette

I have a Marionette CompositeView with a search panel and the collection of result data.

I would like to call a function when:

I did it in this way: (but "afterRender" function get called twice)

// VIEW
App.MyComposite.View = Backbone.Marionette.CompositeView.extend({
    // TEMPLATE
    template: Handlebars.compile(templates.find('#composite-template').html()),
    // ITEM VIEW
    itemView: App.Item.View,
    // ITEM VIEW CONTAINER
    itemViewContainer: '#collection-block',

    //INITIALIZE
    initialize: function() {        
        this.bindTo(this,'render',this.afterRender);
    },

    afterRender: function () {
        //THIS IS EXECUTED TWICE...
    }

});

How can i do this?

==========================EDIT==================================

I solved it in this way, if you have an observation please let me know.

// VIEW
App.MyComposite.View = Backbone.Marionette.CompositeView.extend({

    //INITIALIZE
    initialize: function() {        
        //this.bindTo(this,'render',this.afterRender);
        this.firstRender = true;
    },

    onRender: function () {
        if (firstRender) {
            //DO STUFF HERE..............
            this.firstRender = false;         

        }
    }

});

Upvotes: 5

Views: 19072

Answers (2)

nothing-special-here
nothing-special-here

Reputation: 12618

Just use onShow function

Backbone.Marionette.ItemView.extend({
  onShow: function(){
    // react to when a view has been shown
  }
});

http://marionettejs.com/docs/marionette.view.html#view-onshow

Upvotes: 5

Derick Bailey
Derick Bailey

Reputation: 72888

Marionette provides an onRender method built in to all of it's views, so you can get rid of the this.bindTo(this, 'render', this.afterRender) call:


// VIEW
App.MyComposite.View = Backbone.Marionette.CompositeView.extend({
    // TEMPLATE
    template: Handlebars.compile(templates.find('#composite-template').html()),
    // ITEM VIEW
    itemView: App.Item.View,
    // ITEM VIEW CONTAINER
    itemViewContainer: '#collection-block',

    //INITIALIZE
    initialize: function() {        
        // this.bindTo(this,'render',this.afterRender); // <-- not needed
    },

    onRender: function () {
        // do stuff after it renders, here
    }

});

But to get it to not do the work when the collection is not rendered, you'll have to add logic to the onRender method that checks whether or not the collection was rendered.

This largely depends on what you're trying to do with the rendering when no items are rendered from the collection.

For example... if you want to render a "No Items Found" message, you can use the built in emptyView configuration for the composite view.


NoItemsFoundView = ItemView.extend({
  // ...
});

CompositeView.extend({

  emptyView: NoItemsFoundView

});

But if you have some special code that needs to be run and do certain things that aren't covered by this option, then you'll have to put in some logic of your own.


CompositeView.extend({

  onRender: function(){
    if (this.collection && this.collection.length === 0) {
      // do stuff here because the collection was not rendered
    }
  }

});

Upvotes: 11

Related Questions