简体   繁体   中英

Backbone child view events not firing

I'm a little confused as to why my event is not firing on a child view. I usually set a $el attribute but in this instance I am reusing the child view multiple times so I'm setting the className attribute but it's still not firing.

Here's my code:

Child view (simplified):

var LogbookEntryView = Backbone.View.extend({

    className: 'log-entry',
    collection: Logbook,
    template: _.template($('#logbook-entry-view').html()),

    events: {
        "click .edit-log": "editLog",
        "click .popup": "modalHandler"
    },

    render: function(model) {
        return this.template(model);
    },

    editLog: function(event) {
        var target = $(event.currentTarget);
        var id = $(target).data('id');
        var url = target.attr("href");
        var modal = $(target).data('modal');
        this.loadModal(modal, url);
        return false;
    }
})

Parent view method:

displaySkillsByCat: function() {
    var entryView = new LogbookEntryView();
    _.each(_.keys(app.data), function(cat) {
        $("#logbook-tabs ." + cat).removeClass('disabled');
        $("#" + cat).append(app.template);
        _.each(app.data[cat], function(item) {
            $("#" + cat + " .logbook-list").append(entryView.render(item.attributes));
        });
    })

    return this;
},
    groupSkillsByCategory: function(){
  var cats = _.uniq( this.collection.pluck('cat_group') );
  _.each(cats,  function(cat, index){
    app.data['cat' + cat] = Logbook.where({'cat_group': cat});
  });
},

The problem is that you say you're reusing a view, but in practice, you're not using it at all.

You're just passing data through the render function which returns a string, without any events or anything related to Backbone.

So the first step is to fix the child view class.

  • collection property on a view isn't meant to be used that way, so remove that.
  • A view should fill its el or $el (jQuery equivalent) with a template.
  • render should return this as a standard.
var LogbookEntryView = Backbone.View.extend({
    className: 'log-entry',
    template: _.template($('#logbook-entry-view').html()),

    events: {
        "click .edit-log": "editLog",
        "click .popup": "modalHandler"
    },

    render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    },

    editLog: function(event) {
        var $target = $(event.currentTarget);
        var id = event.currentTarget.id;
        var url = $target.attr("href");
        var modal = $target.data('modal');
        this.loadModal(modal, url);
        return false;
    },
    modalHandler: function() {},
    loadModal: function() {}
});

Then, in the parent view, you could simplify it a bit.

  • Use _.each directly, you do not need _.keys . If it's a Backbone collection, you could use app.data.each(...) .
  • Avoid using the core jQuery function in a loop. Instead, cache the object in a variable, then use it in the loop.
  • Instead of appending the string of the sub view, create a new view and append its el DOMElement.
displaySkillsByCat: function() {
    var entryView = new LogbookEntryView();
    _.each(app.data, function(entries, cat) {
        $("#logbook-tabs ." + cat).removeClass('disabled');
        $("#" + cat).append(app.template);

        // select this element once instead of each iteration
        var $list = $("#" + cat + " .logbook-list");
        _.each(entries, function(item) {

            // here, use `.el` to get the sub-view's element
            $list.append(new LogbookEntryView({ model: item }).render().el);
        });
    })

    return this;
},

The above is a simple fix for your situation, but if you don't keep track of the sub views and they are listening to a Backbone model, there could be memory leaks.

Here's a more efficient way to render a list with Backbone .

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