骨干子视图事件未触发

时间:2017-06-20 00:42:17

标签: javascript jquery backbone.js backbone-views backbone-events

我有点困惑为什么我的事件没有触发子视图。我通常设置一个$el属性,但在这个例子中我多次重复使用子视图,因此我设置了className属性,但它仍未触发。

这是我的代码:

子视图(简化):

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;
    }
})

父视图方法:

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});
  });
},

1 个答案:

答案 0 :(得分:1)

问题是你说你正在重复使用一个视图,但在实践中,你根本就没有使用它。

您只是通过render函数传递数据,该函数返回一个字符串,没有任何事件或任何与Backbone相关的内容。

所以第一步是修复子视图类。

    视图上的
  • collection属性不应该以这种方式使用,因此请删除它。
  • 视图应使用模板填充其el$el(等效的jQuery)。
  • render应返回this作为标准。
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() {}
});

然后,在父视图中,您可以稍微简化一下。

  • 直接使用_.each,您不需要_.keys。如果它是Backbone集合,您可以使用app.data.each(...)
  • 避免在循环中使用core jQuery function。而是在变量中cache the object,然后在循环中使用它。
  • 不是附加子视图的字符串,而是创建一个新视图并附加其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;
},

以上是针对您的情况的简单修复,但如果您不跟踪子视图并且他们正在监听Backbone模型,则可能存在内存泄漏。

这是一个efficient way to render a list with Backbone