javascript 骨干刷新视图事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7260696/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:29:38  来源:igfitidea点击:

Backbone refresh view events

javascriptjquerybackbone.js

提问by keepyourweb

In my view I don't declare this.el because I create it dinamically, but in this way the events don't fire.

在我看来,我不声明 this.el 是因为我是动态创建的,但是这样事件就不会触发。

This is the code:

这是代码:

View 1:

视图 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 );

                    }
});

View 2:

视图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');  
                    }

    });

});

When I click on ".button" nothing happens. Thanks;

当我点击“.button”时,什么也没有发生。谢谢;

回答by Edward M Smith

At the end of your render() method, you can tell backbone to rebind events using delegateEvents(). If you don't pass in any arguments, it will use your events hash.

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

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

回答by Cory Danielson

As of Backbone.js v0.9.0 (Jan. 30, 2012), there is the setElement method to switching a views element and manages the event delegation.

从 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

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

setElementview.setElement(element)

If you'd like to apply a Backbone view to a different DOM element, use setElement, which will also create the cached $el reference and move the view's delegated events from the old element to the new one.

setElementview.setElement(元素)

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





Dynamically creating your views in this fashion has it's pros and cons, though:

不过,以这种方式动态创建视图有利有弊:

Pros:

优点:

  • All of your application's HTML markup would be generated in templates, because the Views root elements are all replaced by the markup returned from the rendering. This is actually kind of nice... no more looking for HTML inside of JS.
  • Nice separation of concerns. Templates generate 100% of HTML markup. Views only display states of that markup and respond to various events.
  • Having render be responsible for the creation of the entire view (including it's root element) is in line with the way that ReactJS renders components, so this could be a beneficial step in the process of migrating from Backbone.Views to ReactJS components.
  • 应用程序的所有 HTML 标记都将在模板中生成,因为 Views 根元素都被渲染返回的标记替换。这实际上是一种很好的...不再在 JS 中寻找 HTML。
  • 很好的关注点分离。模板生成 100% 的 HTML 标记。视图仅显示该标记的状态并响应各种事件。
  • 让 render 负责创建整个视图(包括它的根元素)符合 ReactJS 渲染组件的方式,因此这可能是从 Backbone.Views 迁移到 ReactJS 组件过程中的有益步骤。

Cons:- these are mostly negligible

缺点:-这些几乎可以忽略不计

  • This wouldn't be a painless transition to make on an existing code base. Views would need to be updated and all templates would need to have the View's root elements included in the markup.
    • Templates used by multiple views could get a little hairy - Would the root element be identical in all use cases?
  • Prior to render being called, the view's root element is useless. Any modifications to it will be thrown away.
    • This would include parent views setting classes/data on child view elements prior to rendering. It is also bad practice to do this, but it happens -- those modifications will be lost once render overrides the element.
  • Unless you override the Backbone.View constructor, every view will unnecessarily delegate it's events and set attributes to a root element that is replaced during rendering.
  • If one of your templates resolves to a list of elements rather than a single parent element containing children, you're going have a bad time. setElementwill grab the first element from that list and throw away the rest.
    • Here's an example of that problem, though: http://jsfiddle.net/CoryDanielson/Lj3r85ew/
    • This problem could be mitigated via a build task that parses the templates and ensures they resolve to a single element, or by overriding setElementand ensuring that the incoming element.length === 1.
  • 这不是在现有代码库上进行的无痛转换。视图需要更新,所有模板都需要在标记中包含视图的根元素。
    • 多个视图使用的模板可能会有点麻烦 - 根元素在所有用例中都相同吗?
  • 在调用 render 之前,视图的根元素是无用的。对它的任何修改都将被丢弃。
    • 这将包括父视图在渲染之前在子视图元素上设置类/数据。这样做也是不好的做法,但它会发生——一旦渲染覆盖元素,这些修改就会丢失。
  • 除非您覆盖 Backbone.View 构造函数,否则每个视图都将不必要地委托它的事件并将属性设置为在呈现期间替换的根元素。
  • 如果您的模板之一解析为元素列表,而不是包含子元素的单个父元素,那么您将度过一段糟糕的时光setElement将从该列表中获取第一个元素并丢弃其余元素。
    • 不过,这是该问题的一个示例:http: //jsfiddle.net/CoryDanielson/Lj3r85ew/
    • 这个问题可以通过解析模板并确保它们解析为单个元素的构建任务来缓解,或者通过覆盖setElement并确保传入的element.length === 1.