简体   繁体   English

Backbonejs事件多次触发

[英]Backbonejs events fired multiple times

I developing a table with custom headers/ts and content/td. 我用自定义标题/ ts和内容/ 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 . 好吧,您应该知道的第一件事是$ (this.el)是不必要的,因为主干会自动执行它,并且它会像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") . 因此,它将把'click .entityView':'example'委派给el: $("#entity-items")内部的每个.entityView
That is, the first .entityView will be assigned as many events as there are elements in the table. 也就是说,将为第一个.entityView分配与表中元素数量一样多的事件。 And the last .entityView only 1 event. 最后一个.entityView只有1个事件。

A solution overwriting the delegate method might work: 覆盖delegate方法的解决方案可能会起作用:

// ...extend({
delegate: function(eventName, selector, listener) {
    this.$el.find(selector).last().on(eventName + '.delegateEvents' + this.cid, listener);
    return this;
},
// ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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