在setElement之后,骨干事件未被委托给新元素

时间:2017-07-06 13:04:52

标签: javascript backbone.js underscore.js

我正在使用Underscore模板实现Backbone视图。使用setElement-function将视图el替换为模板html。该函数的声明说“...将视图的委托事件从旧元素移动到新元素”但由于某种原因,这不起作用。任何想法为什么这不像Backbone声明中描述的那样工作?

以下是情况的一个示例(视图的相关部分):

     initialize: function(args) {
        _.extend(this, args);
        this.listenTo(this.model, 'change', this.render);
     },

     events: {
        'click .active-area': '_test'
     },

     _test: function() {
        // After "setElement" this doesn't fire anymore.
        this.model.set('color', 'green');
     },

     render: function() {
        // After this the "click" listener no longer exists.
        this.setElement(this.template(this.model.toJSON());

        return this;
     }

1 个答案:

答案 0 :(得分:2)

this.template(...)不是DOM中的元素。

在您的代码中,setElement从旧元素中删除事件侦听器,然后将它们委托给新元素,它只存在于内存中,而不是页面上。

您应该只改变当前元素的内容。

this.$el.html(this.template(this.model.toJSON()));
  

我需要用模板html替换整个元素html,以及我需要使用setElement函数的原因。

假设您有以下HTML:

<div id="currentView"><!-- view's root (el) -->
    <button type="button" class="active-area">Click me</button>
    <span class="color"><%= color %></span>
</div>

添加包装div并将#currentView div移动到模板中。

<div class="wrapper"><!-- view's root (el) -->
    <div id="currentView">
        <button type="button" class="active-area">Click me</button>
        <span class="color"><%= color %></span>
    </div>
</div>

现在this.$el.html将交换整个元素。

在您真的希望视图交换其自己的根元素的情况下,您可以创建一个新元素,然后使用jQuery&#39; s replaceWith将新元素放在旧元素的位置。< / p>

render: function() {
    // create a new element from the template
    var $newEl = $(this.template(this.model.toJSON()));

    // completely replace the current element in the DOM
    this.$el.replaceWith($newEl);

    // then tell the view
    this.setElement($newEl);

    return this;
}