I developing a table with custom headers/ts and content/td. When i define an event and click in the hooked button, the event fired multiple times:
Views
//VISTA DE CABECERA
var FieldTableHeaders = Backbone.View.extend( {
el: $("#entity-fields tr"),
template: _.template("<th><%= field.Placeholder %></th>"),
initialize: function(){
this.render();
},
render: function() {
console.log(this.model);
$(this.el).append(this.template({
field: this.model
}));
return $(this.el);
},
});
//VISTA DE CONTENIDO
var FieldTableContent = Backbone.View.extend( {
el: $("#entity-items"),
template: _.template($("#fieldActions").html()),
events: {
'click .entityView': 'example'
},
initialize: function(options){
this.render();
},
render: function() {
$(this.el).append(this.template({
field: this.model
}));
return $(this.el);
},
example: function(){
alert('sadasdasd')
}
});
Models
// MODELO DE ENTIDAD UNICA
var CoreEntityModel = Backbone.Model.extend({
defaults: {
_EntityId: null,
_EntityStatus: 0,
_EntityCreateDate: '0000-00-00 00:00:00',
_EntityCreateUser: 0,
_EntityUpdateDate: '0000-00-00 00:00:00',
_EntityUpdateUser: 0
},
idAttribute: "_EntityId"
});
//COLECCIÓN DE ENTIDADES
var EntityCollection = Backbone.Collection.extend({
model: CoreEntityModel
});
//MODELO DE APLICACION
var CoreAplicacionModel = Backbone.Model.extend({
//Instanciar app
defaults: {
ElementsPerPage: 20,
Fields: {},
ID: null,
Name: '',
NameSingular: '',
Permalink: '',
Items: {
Results: [],
Count: 0,
Page: 0
}
},
//Cargar configuracion de app
initialize: function (attrs, opts) {
var self = this;
self.Permalink = attrs;
//Listamos aplicacion
$.ajax(API_PATH + '/apps', {
type: "GET",
dataType: "json",
data: {
permalink: self.Permalink
},
success: function (response) {
var data = response[0];
self.set({
ElementsPerPage: data.ElementsPerPage,
Fields: data.Fields,
ID: data.ID,
Name: data.Name,
NameSingular: data.NameSingular,
Permalink: data.Permalink
});
var Model = self.get('Fields');
var Fields = []
//Recogemos solo campos visibles para cabecera
for (var fieldName in self.get('Fields')) {
if (Model[fieldName].Visible) {
new FieldTableHeaders({
model: Model[fieldName]
});
Fields.push(fieldName);
}
};
self.list(self.get('Items').Page, function(result, data){
if(result){
new FieldTableHeaders({
model: {Placeholder: 'Acciones'}
});
//Recogemos solo campos visibles para contenido
var Items = self.get('Items');
for (var i in Items.Results){
var Values = [];
for (var u in Fields) {
Values.push(Items.Results[i][Fields[u]]);
}
new FieldTableContent({model: Values});
}
}else{
//Ningun registro
}
});
},
error: function (response) {
window.location.href = "pagina-no-encontrada";
}
});
},
// Listar elementos de app
list: function(page, callback){
var self = this;
$.ajax(API_PATH + '/app/'+self.Permalink, {
type: "GET",
dataType: "json",
data: {
page: page
},
success: function (response) {
var Items = self.get('Items');
Items.Page++;
Items.Count = response.count;
for (var item in response.data) {
Items.Results.push(response.data[item]);
}
self.set({Items: Items});
//COLECCIÓN DE ENTIDADES
var entity_collection = new EntityCollection();
entity_collection.add(self.get("Items"));
if (typeof(callback) == "function") {
callback(true, response);
}
},
error: function (response) {
//NO HAY DATOS O ACCESO A API
if (typeof(callback) == "function") {
callback(false, null);
}
}
});
},
idAttribute: "ID"
});
The event fired one time per row in a table.
This is the content template:
<script type="text/html" id="fieldActions">
<tr>
<% _.each(field, function(val, i) { %> <td><%= val %></td> <% }); %>
<td class="text-center">
<a class="btn btn-info btn-rounded btn-xs entityView"><i class="fa fa-eye"></i> Ver</a>
<a class="btn btn-warning btn-rounded btn-xs entityEdit"><i class="fa fa-pencil"></i> Editar</a>
<a class="btn btn-danger btn-rounded btn-xs entityDelete"><i class="fa fa-trash"></i> Eliminar</a>
</td>
</tr>
</script>
What's the problem?
Well, the first thing you should know is that $ (this.el)
is not necessary because backbone does it automatically and it gets like this.$el
.
Answering your question, according to the code , each view delegates its events to each of the elements that are wrapped inside of her.
Therefore it will delegate 'click .entityView':'example'
to each .entityView
that is inside el: $("#entity-items")
.
That is, the first .entityView
will be assigned as many events as there are elements in the table. And the last .entityView
only 1 event.
A solution overwriting the delegate
method might work:
// ...extend({
delegate: function(eventName, selector, listener) {
this.$el.find(selector).last().on(eventName + '.delegateEvents' + this.cid, listener);
return this;
},
// ...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.