0
votes

I'm developing a webapplication with Resthub, so there is a backbone.js stack at the front-side. I need to call a method, everytime a new view (also all sorts of subviews) is rendered, to add some Twitter-Bootstrap specific stuff (help-popovers, kind of quick help, which get their options from a global json file, so the help-texts are easier to maintain).

As far as I know there isn't a backbone-built-in event which is fired every time a view is rendered.

So my question is: What is the easiest way to extend all views, so that they fire an event when the render method is (implicitly or explicitly) called. I want to extend all my views cause I don't want to trigger this event manually in all views I have, because it's error-prone and all developers has to remember that they've to trigger that event.

1
How do you call render() implicitly? Nonetheless, AFAIK you can't. The reason is your views will override Backbone.View. What you can do though is have your actual render code in another method and patch Backbone.View.render to call that method and fire the event. So in your event aggregator or whatever you use for instantiating the views, you will still call render. Internally the views will call _render or whatever you would name the method and trigger the event. Hope this make sense…j03w

1 Answers

2
votes

If you want to do something(fire an event or anything else) for all cases when the render method is called, the most straight forward way might be to update the render method in your copy of Backbone's source code (assuming you want the behavior across the project). By default the render method just returns 'this'

render: function() {
  return this;
},

If there is something you always want to do before render, you can add it within the render method

render: function() {
  //add your extra code/call
  return this;
},

Alternatively you can also override the prototype of Backbone.View function and update/create your own version(s) something like

_.extend(Backbone.View.prototype, Backbone.Events, {
 render: function() {
    console.log('This is a test');
  return this;
}
});

var testView = Backbone.View.extend({
});

var testview = new testView();
testview.render();   //displays This is a test

//any view rendered will now have the console log

Taking this a step further, you can add your own version of render, calling it say 'myrender' and/or add your own event(s) say 'myevent' which can then be called before/after you call render/myrender

_.extend(Backbone.View.prototype, Backbone.Events, {
 render: function() {
    //console.log('This is a test');
  this.mynewevent();
  return this;

 },
 myrender: function() {
    console.log('Pre-render work');
    this.render();
 },
 mynewevent: function() {
    console.log('New Event work');
 }
});

var testView = Backbone.View.extend({
});

var testview = new testView();
//testview.render();
testview.myrender();

Underscore's extend is being used here and since Backbone has a dependency on Underscore, if you are using Backbone, Underscore should be available for you as well.