javascript 我什么时候需要在 Backbone.js 中使用 _.bindAll()?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14513991/
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-26 21:49:47  来源:igfitidea点击:

When do I need to use _.bindAll() in Backbone.js?

javascriptbackbone.js

提问by Anar

I am learning backbone.js, and feel confused on this: I am following the tutorial : http://arturadib.com/hello-backbonejs/

我正在学习backbone.js,对此感到困惑:我正在学习教程:http: //arturadib.com/hello-backbonejs/

as you can see in the first example (1.js):

正如您在第一个示例 (1.js) 中看到的:

(function($){
  var ListView = Backbone.View.extend({    
    el: $('body'), // attaches `this.el` to an existing element.

    initialize: function(){
      _.bindAll(this, 'render'); // fixes loss of context for 'this' within methods

       this.render(); // not all views are self-rendering. This one is.
    },

    render: function(){
      $(this.el).append("<ul> <li>hello world</li> </ul>");
    }
  });

  var listView = new ListView();      
})(jQuery);

But if I comment out the sentence: _.bindAll(this, 'render');, this will still work. I have searched in google and someone said that the method bindAll()is necessary since if I switched my context, the calling of this.rendermay unavailable. I feel confused on the "context". and also could some one explain me when the calling (this.render) will unavailable?

但是如果我注释掉这句话:_.bindAll(this, 'render');,这仍然有效。我在谷歌搜索过,有人说该方法bindAll()是必要的,因为如果我切换上下文,this.render可能无法调用。我对“上下文”感到困惑。当呼叫 ( this.render) 不可用时,有人可以解释一下吗?

回答by Dennis Rongo

For the example you've given _.bindAll(this, 'render');isn't necessary but if you have callback functions where thiscan possibly be changed to the context of something else, then _bindAll()can be handy.

对于您给出的示例,_.bindAll(this, 'render');不是必需的,但是如果您有回调函数,this可以将其更改为其他内容的上下文,那么_bindAll()可能会很方便。

For instance:

例如:

initialize: function(){
  _.bindAll(this, 'render', 'clickFunc');
},
events: {
   'click .someElement': 'clickFunc'
},
clickFunc: function(e) {
   /** If you remove the clickFunc from the list of events in bindAll, 
          'this' will refer to the element that invoked the event.

       Adding the clickFunc event in the _.bindAll, ensures that 'this' stays
          as the view.
   */
  this /** <-- our focal point */
}

回答by Peter Lyons

  • Any methods listed as property values in your view's events hash are automatically bound for you by backbone
  • Any methods in your view that you manually use as event handlers from models or collections should be manually bound via bindAll
    • OR you can provide a context when you register the binding
    • OR you can use EMCA 5's function.bindto get the same result
  • 在您的视图事件哈希中列为属性值的任何方法都将通过主干自动绑定到您
  • 视图中手动用作模型或集合中的事件处理程序的任何方法都应通过以下方式手动绑定 bindAll
    • 或者您可以在注册绑定时提供上下文
    • 或者您可以使用 EMCA 5 的function.bind来获得相同的结果

snippet:

片段:

events: {
    'click .win': 'win',
    'click .lose': 'lose'
},
initialize: function () {
    //win and lose are automatically bound for you
    //because they are in the events property

    //refresh must be manually bound
    this.model.on('change', this.refresh);

    //which you can do ECMA5 style if you like
    this.model.on('change', this.refresh.bind(this));

    //OR you can provide a context backbone style
    this.model.on('change:foo', this.fooChange, this);

    //However, since you pretty much never want an unbound function
    //in a view, you can just stick this in all your initialize methods
    //and call it done
    //Note this will bind all functions in your view class if you don't
    //pass specific method names. I recommend this form.
    _.bindAll(this);
},
win: function () {...},
lose: function () {...},
refresh: function () {...},
fooChange: function() {...}

...OOOOORRRRjust use CoffeeScript and fat arrows and solve this cleanly at the language level.

... OOOOORRRR只需使用 CoffeeScript 和箭头并在语言级别干净地解决这个问题。

回答by Bassam Mehanni

in this instance you don't need the _.bindAll, but let's say your view have a method that causes a rerender and you do something like this:

在这种情况下,您不需要_.bindAll,但假设您的视图具有导致重新渲染的方法,并且您执行以下操作:

..,
myMethod: function() {
    this.$('.someselector').change(this.render);
},

if you don't have _.bindAllfor render, your context would be off.

如果你没有_.bindAllfor render,你的上下文就会关闭。

回答by Alan Dong

Lets take a close look at what _.bindAlldoes from underscore.js offical docs.

让我们在什么密切关注_.bindAll来自确实underscore.js官方文档

  _.bindAll = function(obj) {
    var i, length = arguments.length, key;
    if (length <= 1) throw new Error('bindAll must be passed function names');
    for (i = 1; i < length; i++) {
      key = arguments[i];
      obj[key] = _.bind(obj[key], obj);
    }
    return obj;
  };

What it does is to automatically bind all its functions to its correct context. (where its function is declared rather than invoked.

它所做的是自动将其所有功能绑定到其正确的上下文。(它的函数被声明而不是被调用。

I personally think it was a convention for old version of Backbone.js to bind its events, or DOM action listeners. Since new versions Backbone Viewautomatically bind and unbind listeners in events. Find more by search Binding "this"here

我个人认为这是旧版本的 Backbone.js 绑定其events或 DOM 动作侦听器的约定。由于新版本 BackboneView自动绑定和解除绑定events. 通过搜索找到更多Binding "this"这里

I hope it helps.

我希望它有帮助。