骨干事件处理程序不起作用

时间:2016-10-06 11:07:47

标签: javascript jquery backbone.js

我有两个视图 - 布局视图,它是顶级视图,以及一个新的窗体视图,它充当布局的子窗口并在其中呈现。我在表单视图中有一个事件处理程序,它应该根据输入中的数据创建我的模型的新实例。

这是布局视图:

var LayoutView = Backbone.View.extend({
    el: "#layout",
    render: function (view) {
        this.child = view;
        if (this.child) {
            this.child.remove();
        }
        this.$el.html(this.child.render().el);
        return this;
    }
});

以及此处的表单视图:

var ResumeForm = Backbone.View.extend({
    events: {
        'click #create': 'createResume'
    },
    initialize: function () {
        this.template = _.template($('#new-resume').html());
    },
    render: function () {
        this.$el.html(this.template());
        return this;
    },
    createResume: function () {
        // getting values from template inputs and saving them to model
        var resume = new Resume({
            profession: $('#profession').val(),
            firstName: $('#firstname').val(),
            lastName: $('#lastname').val()
        });
        // saving a new model to collection instance
        resumes.add(resume);
        resume.save(null, {
            success: function (res) {
                console.log("POST resume id " + res.toJSON().id);
            },
            error: function () {
                console.log("Failed to POST");
            }
        });
    }
});

我的表单视图在我的布局视图中完美呈现,但是当我输入值并单击#create按钮时,没有任何反应 - 既不保存模型也不记录createResume方法中的任何错误错误。我怀疑在布局视图中渲染表单视图时,行this.$el.html(this.child.render().el);只会破坏所有事件侦听器,因为如果我将这些侦听器添加到布局视图中,它就可以工作。

有没有办法覆盖这个问题?

1 个答案:

答案 0 :(得分:1)

Backbone的视图remove函数取消激活绑定到el的事件。

来自annotated source

remove: function() {
    this._removeElement();
    this.stopListening();
    return this;
},

_removeElement: function() {
    this.$el.remove();
},

这与jQuery .remove()函数(强调我的)有关:

  

.empty()类似,.remove()方法从DOM中获取元素。如果要删除元素本身及其中的所有内容,请使用.remove()。除了元素本身之外,还删除了与元素关联的所有绑定事件和jQuery数据。要删除元素而不删除数据和事件,请改用.detach()

如果在重新使用视图之前调用remove,则需要手动调用this.delegateEvents()以重新绑定events哈希中的事件,并重新连接视图的任何事件。通过this.listenTo(...)收听。

但重新使用视图的最佳方法是,在不调用调用remove的{​​{1}}的情况下,您可以使用stopListening取消激活事件,并将视图元素更改为传递的元素,然后重新委派事件。

setElement

您的setElement: function(element) { this.undelegateEvents(); this._setElement(element); this.delegateEvents(); return this; }, 会变成这样:

LayoutView