After Render Event on CompositeView with Backbone.Marionette
Asked Answered
A

2

5

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

I would like to call a function when:

  • the search panel is rendered.
  • the collection is not rendered yet.
  • this function should not be called when the collection is rendered.

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;         

        }
    }

});
Alliterate answered 30/8, 2012 at 22:5 Comment(2)
Please provide some more details on your event bindings and when reneder is calledCecum
It's in the initialize function: "this.bindTo(this,'render',this.afterRender)". I'm not sure if this is right, but what i want to to do is call "afterRender" function once the view is renderedAlliterate
B
11

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
    }
  }

});
Betelgeuse answered 31/8, 2012 at 11:58 Comment(1)
Thanks for your answer. Maybe this : "this.collection.length > 0" should be changed by "this.collection.length == 0"Alliterate
X
5

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

X answered 1/4, 2015 at 16:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.