29

Does anyone know which event is fired after a view is rendered in backbone.js?

Josh Earl
  • 18,151
  • 15
  • 62
  • 91
schlubbi
  • 1,623
  • 2
  • 13
  • 17

7 Answers7

38

I ran into this post which seems interesting

var myView = Backbone.View.extend({ 

    initialize: function(options) { 
        _.bindAll(this, 'beforeRender', 'render', 'afterRender'); 
        var _this = this; 
        this.render = _.wrap(this.render, function(render) { 
            _this.beforeRender(); 
            render(); 
            _this.afterRender(); 
            return _this; 
        }); 
    }, 

    beforeRender: function() { 
       console.log('beforeRender'); 
    }, 

    render: function() { 
        return this; 
    }, 

    afterRender: function() { 
        console.log('afterRender'); 
    } 
});
abritez
  • 2,616
  • 3
  • 29
  • 36
  • 1
    Why do you need this line: `_.bindAll(this, 'beforeRender', 'render', 'afterRender');`? – pilau Jul 10 '13 at 13:52
  • 2
    @pilau - Refer [this](http://blog.bigbinary.com/2011/08/18/understanding-bind-and-bindall-in-backbone.html) for understanding _.bind and _.bindAll. It helped me, hope it would help you too. – arunkjn Jul 18 '13 at 09:31
  • 1
    I know what it does, I am inquiring about why you require using it at all, since they (the functions), are all extending the view object anyway? – pilau Jul 18 '13 at 11:05
  • 1
    Just to help clarify: To add your own functions to the model and collection, you have to use bindAll. This is not the case for the view they are 'bound' automatically. – John Moses Jul 22 '13 at 15:50
  • 1
    @JohnMoses Exactly my point, they are already part of the View object – pilau Sep 08 '13 at 17:19
  • @abritez How can I get this working if I want to pass parameters to render function? If I change the definition to ```render: function(opts)``` I can't access ```opts``` object. – Deniz Ozger Jun 02 '15 at 15:39
  • If you dont use `Function.prototype.bind`, `_.bind`, or `_.bindAll`, the context of `render()` will be `window` – nickford Jan 27 '17 at 15:33
24

Or you can do the following, which is what Backbone code is supposed to look like (Observer pattern, aka pub/sub). This is the way to go:

var myView = Backbone.View.extend({ 
    initialize: function() {  
        this.on('render', this.afterRender);

        this.render();
    },

    render: function () {  
        this.trigger('render');
    },

    afterRender: function () {
    }
});

Edit: this.on('render', 'afterRender'); will not work - because Backbone.Events.on accepts only functions. The .on('event', 'methodName'); magic is made possible by Backbone.View.delegateEvents and as such is only available with DOM events.

pilau
  • 6,635
  • 4
  • 56
  • 69
  • Uncaught TypeError: Object afterRender has no method 'call' – Trip Jul 09 '13 at 19:08
  • 1
    @Trip Fixed. Didn't think it would matter but apparently it doesn't work with the name of the method alone. I now have to find out why. – pilau Jul 10 '13 at 06:29
  • 1
    @PHPst: What is the purpose of your edit, i.e. changing `render` to show`? – Colin Brock Dec 10 '13 at 05:09
  • 2
    @PHPst: The custom event being triggered is named `render`, as in `this.trigger('render');`. Where are you getting `show` from? Do you have a link to some documentation? As far as I know, there is no Backbone event called `show`. – Colin Brock Dec 10 '13 at 05:38
  • 2
    @PHPst Your edit completely breaks my code, you see that line `this.trigger('render');`? Well, because I'm registering `this.afterRender` on the `render` event (a custom event, not part of Backbone), `this.afterRender` will get fired after the template is rendered. I don't know why did you make that edit, by I'm reverting it. By the way, the word "show" doesn't even appear in the Backbone annotated source... – pilau Dec 10 '13 at 08:33
  • @pilau I wonder why `render` do not work for my but `show` works. I will investigate on it. – Handsome Nerd Dec 10 '13 at 09:29
  • @PHPst Great, let us know! – pilau Dec 10 '13 at 13:26
  • 1
    After trying a ton of fixes, this one worked out best for me. Thanks pilau – GONeale Apr 21 '15 at 00:17
  • @GONeale Sure buddy :) The correct way is always the best way! – pilau May 21 '15 at 19:04
18

As far as I know - none is fired. Render function is empty in source code.

The default implementation of render is a no-op

I would recommend just triggering it manually when necessary.

Max Smolens
  • 3,461
  • 26
  • 34
Arnis Lapsa
  • 45,880
  • 29
  • 115
  • 195
2

If you happen to be using Marionette, Marionette adds show and render events on views. See this StackOverflow question for an example.

On a side note, Marionette adds a lot of other useful features that you might be interested in.

Community
  • 1
  • 1
Jon Onstott
  • 13,499
  • 16
  • 80
  • 133
1

I realise this question is fairly old but I wanted a solution that allowed the same custom function to be called after every call to render, so came up with the following...

First, override the default Backbone render function:

var render = Backbone.View.prototype.render;
Backbone.View.prototype.render = function() {
    this.customRender();
    afterPageRender();
    render();
};

The above code calls customRender on the view, then a generic custom function (afterPageRender), then the original Backbone render function.

Then in my views, I replaced all instances of render functions with customRender:

initialize: function() {
    this.listenTo(this.model, 'sync', this.render);
    this.model.fetch();
},

customRender: function() {
    // ... do what you usually do in render()
}
b4tch
  • 959
  • 9
  • 16
-1

Instead of adding the eventhandler manually to render on intialization you can also add the event to the 'events' section of your view. See http://backbonejs.org/#View-delegateEvents

e.g.

events: {
   'render': 'afterRender'
}

afterRender: function(e){
    alert("render complete")
},
dhr_p
  • 2,364
  • 1
  • 22
  • 19
  • This doesn't work. Delegate Events refer to events that occur on the dom. Not callbacks on the view object itself. – louism2 Mar 20 '14 at 16:39
  • `events` is used for `declarative callbacks for DOM events`, see [backbone/#View-delegateEvents](http://documentcloud.github.io/backbone/#View-delegateEvents) – RainChen Aug 02 '14 at 03:32
-3
 constructor: function(){
   Backbone.View.call(this, arguments);     
   var oldRender = this.render
   this.render = function(){
      oldRender.call(this)
      // this.model.trigger('xxxxxxxxx')
   }       
 }

like this http://jsfiddle.net/8hQyB/

user873792
  • 323
  • 2
  • 8