Catching remove event on View in Backbone js - backbone.js

Is there any way to listen to remove/destroy event on the Backbone View.?
I want to do some thing like as below:
$(myBackboneView).on('remove', function () {
// do some processing
});
or
$(myBackboneView).on('destroy', function () {
// do some processing
});
Thank you in advance. :)

You can try to override the View.remove method::
Backbone.View.extend({
remove: function(){
// Your processing code here
Backbone.View.prototype.remove.apply(this, arguments);
};
});

I tried the following and it works for me:
$(myBackboneView.el).on('remove', function () {
// do some processing
});
Is this is a good approach ? Or there is something else better than this?

If you need to listen for other views being removed, you can have your base View class trigger a 'remove' event when remove() is called.
BaseView = Backbone.View.extend({
remove: function () {
this.trigger('remove', this)
return Backbone.View.prototype.remove.apply(this, arguments)
}
})
Then listen for that whenever you like:
this.listenTo(otherView, 'remove', func)

Related

Backbone trigger event after custom function possible?

Excuse my backbone i'm not an expert, Must execute function Show absolutely and only after ResetQuestions
ResetQuestions:function () {
//Great Code Here
}),
I tried this:
initialize: function () {
this.on("Show", this.Show, this);
},
ResetQuestions:function () {
//Great Code Here
this.trigger("Show");
}),
But that was unsuccessful, does anyone know how i can accomplish this?
no need of events you can simply call the function from other function
var sampleView = Backbone.View.extend({
initialize: function () {
this.ResetQuestions();
},
Show: function () {
alert('i am at show');
},
ResetQuestions: function () {
// Execute all you code atlast call Show function as below.
this.Show();
}
});
var view = new sampleView();
var sampleView = Backbone.View.extend({
initialize: function(){
this.ResetQuestions().promise().done(function() { // Using promise here.
this.Show();
});
},
Show: function(){
},
ResetQuestions: function(){
// Execute all you code atlast call Show function as below.
}
});
Then initiate your view,
var view = new sampleView();
Hope this works!!
Perhaps you just got confused what runs what and by naming event and method with same name Show. I have created a jsfiddle with your code - http://jsfiddle.net/yuraji/aqymbeyy/ - you call ResetQuestion method, it triggers Show event, and the Show event runs Show method.
EDIT: I have updated the fiddle to demonstrate that you probably have to bind the methods to the instance, I used _.bindAll for that. If you don't do that you may get event as the context (this).
EDIT: Then, if your ResetQuestions runs asynchronous code, like an ajax request to get new questions, you will have to make sure that your Show event is triggered when the request is completed.

listenTo not working when using in another view in backbone.js

I am a newbee to backbone.I have a view called AbcView
abc.js
var AbcView = Backbone.View.extend({
events: {
"click" : "display",
},
display: function(e){
console.log("hello");
alert("click function");
}
});
Now I am passing this abc.js to another xyz.js file and calling it in another view using ListenTo.
xyz.js
var xyzView = Backbone.View.extend({
initialize: function(){
var AbcView = new AbcView ();
this.lisenTo(AbcView, "click",this.display);
},
render: function(){
var html = this.template(AbcView);
this.$el.html(html);
return this;
},
display: function(e){
console.log("parent hello");
alert("parent display function");
}
});
With abc.js click event is triggering fine. But with xyz.js click event is not triggering.
Is this the correct way to call listenTo.
DOM events aren't delegated on the View object.
If you want to emulate this though, you'd have to manually emit the event in ABC display method:
display: function(e){
// Trigger manually
this.trigger("click");
// Your usual code
console.log("hello");
alert("click function");
}
In term of best practice, I'd probably rename "click" to a more descriptive event name.
Backbone's on and listenTo are intended for listening to events on Backbone Models and Collections.
http://backbonejs.org/#Events-catalog
This is an important thing to understand. It is not the same as UI event binding, as described in http://backbonejs.org/#View-delegateEvents.
That being said, you can use something like what Simon suggests to intermingle the two.

backbone boilerplate render view issue

I am using the backbone-boilerplate/backbone-layoutmanager, and I am having issues re-rendering the view after calling place.fetch(). It seems to work fine the first time, but when I do fetch the second time, the "render" method is not getting called anymore.
Any hints would be helpful
thanks
pete
ROUTER
test: function() {
var place = new Place.Model({
place_id: place_id,
});
place.fetch().complete(function(){
app.useLayout("main").setViews({
".place-detail": new Place.Views.Show({
model: place
})
}).render();
});
}
VIEW
initialize: function() {
_.bindAll(this, "render");
this.model.on("change", this.render, this);
}
render: function(manage) {
return manage(this).render();
}
fetch is an async function which accepts an object with a success or error handler which will be called on completion. AFAIK fetch does not support the jQuery method of chaining with a complete handler, so you need to pass it an object with the proper success method set up if you want it called on completion.

Listen to body click inside a view with backbone.js

I'm creating a modal dialog like this
window.NewPageModalView = Backbone.View.extend({
template: _.template($('#view-template-new-page-dialog').html()),
el: $('div#main'),
events: {
'click input[type=radio]': 'newPage'
},
newPage: function (event) {
$(event.currentTarget).closest('form').submit();
},
initialize: function () { },
render: function () {
$(this.el).append(this.template());
return this;
}
});
and then I create it inside another view like this
addPage: function (event) {
event.preventDefault();
var modal = new NewPageModalView();
modal.render();
}
this works just great but what is the best way if I want to close the dialog on body click or when pressing escape?
Generally speaking when you bind events in backbone using the events hash they are delegated to the view's el, however you can still bind events to something else in the initialize method (in your case the body).
initialize: function() {
$('body').bind('click', yourfunction);
}
Edit:
As #muistooshort mentions, you will want to make sure to also unbind the event.

Backbone.js event after view.render() is finished

Does anyone know which event is fired after a view is rendered in backbone.js?
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');
}
});
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.
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.
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.
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()
}
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")
},
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/

Resources