I have method in model:
decrease: function(){
this.save({
count: this.get('count') - 1
});
}
Next, i call method in view for event:
'click [data-skills="minus"]': 'decrease'
And from this method, i call method from model: (#3)
decrease: function(){
this.model.decrease();
}
Is there some way to call model's method directly from events? Without step #3.
events: {
'click [data-skills="minus"]': function(){
this.model.decrease();
}
}
Related
I have a div generated by a backbone.js view. When the user clicks on this div, a class active is added to the div and the function addToSet is executed.
Problem: I want another function to be triggered when the View's div has the class active. However, my attempt shown below always cause addToSet function to run when its clicked.
Now, I remove 'click': 'addToSet' from the events function, leaving only 'click .active': 'removeFromSet'. Clicking on the div does not cause anything to happen! Is this because the event handler cannot select the div of the view itself, just the elements inside it?
Any idea how I can solve this problem? Thanks!
JS Code
SetView = Backbone.View.extend({
tagName: 'div',
className: 'modal_addit_set',
template: _.template( $('#tpl_modal_addit_set').html() ),
events: {
'click': 'addToSet',
'click .active': 'removeFromSet'
},
initialize: function(opts) {
this.post_id = opts.post_id;
},
render: function() {
$(this.el).html( this.template( this.model.toJSON() ) );
if(this.model.get('already_added'))
$(this.el).addClass('active');
return this;
},
addToSet: function() {
$.post('api/add_to_set', {
post_id: this.post_id,
set_id: this.model.get('id'),
user_id: $('#user_id').val()
});
},
removeFromSet: function() {
$.post('api/remove_from_set', {
post_id: this.post_id,
set_id: this.model.get('id')
});
}
});
Have you tried to use a :not(.active) selector for one of your event delegates? This may help differentiate between the two scenarios.
Something like this:
events: {
'click :not(.active)' : callback1
'click .active' : callback2
}
These events:
events: {
'click': 'addToSet',
'click .active': 'removeFromSet'
}
don't work and you sort of know why. From the fine manual:
Events are written in the format {"event selector": "callback"}. The callback may be either the name of a method on the view, or a direct function body. Omitting the selector causes the event to be bound to the view's root element (this.el).
So your 'click': 'addToSet' binds addToSet to a click on the view's el itself but 'click .active': 'removeFromSet' binds removeFromSet to a .active element inside the view's el.
I think the easiest solution is to have a single event:
events: {
'click': 'toggleInSet'
}
and then:
toggleInSet: function() {
if(this.$el.hasClass('active')) {
$.post('api/remove_from_set', {
post_id: this.post_id,
set_id: this.model.get('id')
});
}
else {
$.post('api/add_to_set', {
post_id: this.post_id,
set_id: this.model.get('id'),
user_id: $('#user_id').val()
});
}
}
You could use an instance variable instead of a CSS class to control the branching in toggleInSet if that makes more sense.
i want to call a method from view#1 which is already implemented in different view (view#2)..
how to achieve this in a nice n simple way.. using backbonejs.
App.Views.view1 = Backbone.View.extend({
events: {
'click .someclass1' : 'custom_method_1',
},
custom_method_1:function(e){
//now this method calls another method which is implemented in different view
custom_method_2();
},
});
App.Views.view2 = Backbone.View.extend({
events: {
'click .someclass2' : 'custom_method_2',
},
//// this method needs to be called from view1 also
custom_method_2:function(e){
},
});
If you search how to use the eventbus, you can do it like this:
// you can name the event 'custom_method_2' as you want
Backbone.Events.on('custom_method_2', App.Views.view2.custom_method_2);
Now you are listening to the event custom_method_2 on the Object Backbone.Events that you can consider as your eventsbus.
Then in view1:
custom_method_1:function(e){
//now this method calls another method which is implemented in different view
// custom_method_2();
Backbone.Events.trigger('custom_method_2', e);
},
I have this collection with an over-riden parse method. I want a method in my view to be called when the collection is finished with parse
This collection will be calling sync and so parse only once.
I tried this.collection.on("reset", this.more, this); but that doesn't work.
more: function() {
var users = this.collection.slice( this.index, this.index + this.load_once), that = this;
this.index = this.index + this.load_once;
_.each( users, function( user ){
that.addOne( user );
});
},
addOne: function( user ){
var view = new UserView({model: user});
this.$("#user_list").append(view.render().el);
}
The reset method will be triggered when {reset: true} option is passed to the fetch. You can listen to the add and sync that will fire this method. Also use this.listenTo bind the events in a cleaner manner.
initialize: function() {
... some other code
this.listenTo(this.collection, "add sync", this.more);
this.collection.fetch();
}
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.
I'm trying to add the functionality to my app so I can update my database and then update the DOM. The database gets updated fine, but the DOM doesn't. Here is part of my view:
App.Views.Table = Backbone.View.extend({
tagName: 'span',
initialize: function(options) {
this.model.on('change', this.render, this);
this.model.on('update', this.remove, this);
this.template = this.options.template;
this.url = this.options.url;
},
events: {
'click .verify': 'verify',
'click .spam': 'spam',
'click .duplicate': 'duplicate'
},
verify: function(e) {
id = e.currentTarget.id;
table = new App.Models.Table({ id: id });
table.urlRoot = this.url;
table.fetch();
table.toJSON();
table.set('verified', 1);
table.save();
},
spam: function(e) {
...
},
duplicate: function(e) {
...
},
remove: function() {
this.$el.remove();
console.log('hello');
},
retrieveTemplate: function(model) {
return _.template($('#' + this.template).html(), model);
},
render: function() {
//console.log(this);
this.$el.html(this.retrieveTemplate(this.model.toJSON()));
return this;
}
});
As I understand it, this.model.on('update', this.remove, this); should call my remove function when save completes. But the callback isn't firing because I'm not getting the console.log and my DOM isn't being updated. What am I doing wrong? I followed a tutorial, but everything works fine in the tutorial.
There is no update event. I think you mean sync
http://backbonejs.org/#Events-catalog
"sync" (model, resp, options) — when a model has been successfully synced with the server.
Also a helpful hit for debugging that I found was using the all event to see what events are getting triggered.
Edit:
After some debugging, the goal of the verify() function was to save the verified attribute to the model. To do that we needed to change verify() to
this.model.set('verified', 1);
this.model.save();
instead of creating a new App.Model.Table and setting it to the table variable. Doing table .save() was saving the new table model, instead of the old model, this.model. That's why the event handlers attached to this.model were net getting triggered.
There are no "create" or "update" events in Backbone.js. That's why your remove() callback isn't firing.
See http://backbonejs.org/#Events-catalog for a catalog of the possible events in Backbone.
UPDATE:
After looking at your code more closely, the answer is clear. They are different models:
initialize: function(options) {
this.model.on('change', this.render, this);
this.model.on('sync', this.remove, this);
and
table = new App.Models.Table({ id: id });
...
table.save();
The events that occur on your table object are not going to trigger event handlers that are bound to a totally different model (this.model).
Why create another model (table) when you already had a model? (this.model) ?
* UPDATE *
I don't really understand what you're trying to do, but perhaps try this:
table = new App.Models.Table({ id: id });
table.on('sync', this.remove, this);