简体   繁体   中英

Backbonejs events fired multiple times

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM