Reputation: 4321
RoomsDGView = Backbone.View.extend({
collection: roomcollection,
initialize: function(){
var template = _.template( $("#search_template").html(), {} );
this.$el.html( template );
this.collection.bind('add', this.modeladded);
this.collection.bind('remove', this.modelremoved);
this.collection.bind('change', this.collectionchanged);
console.log(this);
this.render();
},
render: function(){
// Compile the template using underscore
console.log("running the render function...");
//renderrender();
/*$("#roomsList").jqGrid('clearGridData');
roomcollection.each(function (room,i){
var temp = jQuery.parseJSON(JSON.stringify(room));
$("#roomsList").jqGrid('addRowData', i,{idrooms: temp["idrooms"], roomname: temp["roomname"],
occupants: temp["occupants"]});
});*/
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function(){
// Button clicked
console.log(this);
},
modeladded: function() {
console.log("room added...");
$("#roomsList").jqGrid('clearGridData');
//My intent is to call the views render function
//her. I tried using this.render() and also
//this.collection.bind('add', this.modeladded(this));
//modeladded: function(view) {
// view.render();
console.log(this);
},
modelremoved: function() {
console.log("room removed...");
$("#roomsList").jqGrid('clearGridData');
},
collectionchanged: function() {
console.log("room changed...");
$("#roomsList").jqGrid('clearGridData');
}
});
I have tried many different ways to call the views render: method from inside the code for modeladded:. Use of this.render inside model added shows that the this object at that point has no render function. I also tried passing the view in something like:
this.collection.bind('add', this.modeladded(this));
modeladded: function(view) { view.render();
which also leads to a console error that no render() can be found. Does anyone know how to call the views render: from inside modeladded?
For the time being I moved the render function out of the views render: and into a JavaScript function declared renderGlobal() declared in global scope and I know it does work that way but I don't think that is really the backbone.js way.
This is the error that is coming out of the console: Uncaught TypeError: Object [object Object] has no method 'render'
Thank you for posting....
Upvotes: 1
Views: 598
Reputation: 434635
You're binding your event handler using bind
(AKA on
):
this.collection.bind('add', this.modeladded);
But, as usual with JavaScript, the value of this
inside a function depends on how the function is called, not how it is defined (ignoring bound functions of course). You're not specifying a specific this
for your function anywhere so you're not getting any particular this
when it is called. If you give bind
the third context argument:
this.collection.bind('add', this.modeladded, this);
// ------------------------------------------^^^^
then Backbone will call modeladded
with the specific this
and you'll find that this
inside modeladded
will be your view.
You could also use _.bind
, Function.prototype.bind
, or $.proxy
to produce a bound version of your callback:
this.collection.bind('add', _(this.modeladded).bind(this));
this.collection.bind('add', this.modeladded.bind(this));
this.collection.bind('add', $.proxy(this.modeladded, this));
All of those produce new functions so you won't be able to unbind
them without stashing the bound functions somewhere. You'll usually avoid using these when you have the option to specify the context (AKA this
) explicitly.
There's also listenTo
:
listenTo
object.listenTo(other, event, callback)
Tell an object to listen to a particular event on an other object. The advantage of using this form, instead of
other.on(event, callback, object)
, is that listenTo allows the object to keep track of the events, and they can be removed all at once later on. The callback will always be called with object as context.
So you can (and should) say this:
this.listenTo(this.collection, 'add', this.modeladded);
That will take care of giving you the desired this
and makes it easier to clean up your event handlers when you're done with them. Similarly for the other event handlers you're using.
Upvotes: 3