Backbone刷新视图事件

10

在我看来,我没有声明this.el,因为我是动态创建它的,但这样做事件无法触发。

下面是代码:

视图1:

App.Views_1 = Backbone.View.extend({

    el:             '#content',

    initialize:     function() {    
                        _.bindAll(this, 'render', 'renderSingle');                          
                    },

    render:         function() {    
                        this.model.each(this.renderSingle);                 
                    },

    renderSingle:   function(model) {

                        this.tmpView = new App.Views_2({model: model});                     
                        $(this.el).append( this.tmpView.render().el );

                    }
});

视图2:

App.Views_2 = Backbone.View.extend({

    initialize:     function() {                                
                        _.bindAll(this, 'render');                      
                    },

    render:         function() {    
                        this.el = $('#template').tmpl(this.model.attributes);       // jQuery template                          
                        return this;                            
                    },

    events:         {       
                        'click .button' :       'test'                  
                    },

    test:           function() {        
                        alert('Fire');  
                    }

    });

});

当我点击“.button”时,没有任何反应。 谢谢;


假设 #template 包含一个类为 '.button' 的按钮,这应该可以工作。你能发布一下你的 #template 内容吗? - Derick Bailey
2个回答

20

在你的render()方法结束时,你可以使用delegateEvents()告诉backbone重新绑定事件。如果你不传递任何参数,它将使用你的事件哈希表。

render:         function() {    
                    this.el = $('#template').tmpl(this.model.attributes);       // jQuery template                          
                    this.delegateEvents();
                    return this;                            
                }

1
自Backbone.js v0.9.0(2012年1月30日)起,有一个setElement方法,用于切换视图元素并管理事件委托。
render: function() {
    this.setElement($('#template').tmpl(this.model.attributes));
    return this;
}

Backbone.View setElement: http://backbonejs.org/#View-setElement

setElementview.setElement(element)

如果您想将Backbone视图应用于不同的DOM元素,请使用setElement,它还将创建缓存的$el引用并将视图的委托事件从旧元素移动到新元素。



动态创建视图的方式有其优缺点:
优点:
  • 应用程序所有的HTML标记都将在模板中生成,因为视图根元素都会被渲染返回的标记所替换。这样做很好,不再需要在JS中查找HTML。
  • 关注点分离。模板生成100%的HTML标记。视图只显示该标记的状态并响应各种事件。
  • 让render函数负责整个视图(包括其根元素)的创建与ReactJS组件呈现方法一致,因此这可能是从Backbone.Views向ReactJS组件迁移过程中的一个有益步骤。
缺点: - 这些大多可以忽略
  • 在现有的代码库中进行这种转换不会是一个无痛的过渡。视图需要更新,所有模板都需要在标记中包含视图的根元素。
    • 多个视图使用的模板可能会变得有些混乱 - 在所有用例中,根元素是否相同?
  • 在调用渲染之前,视图的根元素是无用的。对它的任何修改都将被丢弃。
    • 这将包括父视图在呈现之前在子视图元素上设置类/数据。 这也是不好的做法,但它确实发生了 - 这些修改将在渲染覆盖元素时丢失。
  • 除非你重写Backbone.View构造函数,否则每个视图都会不必要地将其事件委托和属性设置到在渲染期间被替换的根元素上。
  • 如果你的模板解析为一个包含子元素的单个父元素而不是元素列表,你会遇到麻烦setElement将从该列表中获取第一个元素并丢弃其余部分。
    • 以下是该问题的示例,http://jsfiddle.net/CoryDanielson/Lj3r85ew/
    • 这个问题可以通过一个解析模板并确保它们解析为单个元素的构建任务来缓解,或者通过重写setElement并确保传入的element.length === 1来缓解。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接