Подтвердить что ты не робот

Когда мне нужно использовать _.bindAll() в Backbone.js?

Я изучаю backbone.js и чувствую смущение этим: Я следую руководству: http://arturadib.com/hello-backbonejs/

как вы можете видеть в первом примере (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);

Но если я прокомментирую предложение: _.bindAll(this, 'render');, это все равно будет работать. Я искал в google, и кто-то сказал, что метод bindAll() необходим, так как если бы я переключил свой контекст, вызов this.render может быть недоступен. Я чувствую смущение от "контекста". а также может ли кто-нибудь объяснить мне, когда вызов (this.render) будет недоступен?

4b9b3361

Ответ 1

Для примера, который вы указали _.bindAll(this, 'render');, не обязательно, но если у вас есть функции обратного вызова, где this можно изменить в контексте чего-то другого, тогда _bindAll() может быть удобно.

Например:

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 */
}

Ответ 2

  • Любые методы, перечисленные как значения свойств в вашем представлении, хеш событий автоматически привязаны к вам по магистрали
  • Любые методы, которые вы используете вручную как обработчики событий из моделей или коллекций, должны быть связаны вручную через bindAll
    • ИЛИ вы можете предоставить контекст при регистрации привязки
    • ИЛИ вы можете использовать EMCA 5 function.bind, чтобы получить тот же результат

сниппет:

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() {...}

... OOOOORRRR просто используйте CoffeeScript и жирные стрелки и решите это на уровне языка.

Ответ 3

в этом случае вам не нужен _.bindAll, но пусть у вашего представления есть метод, который вызывает повтор, и вы делаете что-то вроде этого:

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

если у вас нет _.bindAll для render, ваш контекст будет отключен.

Ответ 4

Давайте внимательно рассмотрим, что _.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;
  };

Что он делает, так это автоматически привязывать все свои функции к правильному контексту. (где его функция объявлена, а не вызывается.

Я лично считаю, что для старой версии Backbone.js это было соглашение, чтобы связать своих слушателей действий events или DOM. Поскольку новые версии Backbone View автоматически связывают и отвязывают прослушиватели в events. Найти больше по запросу Binding "this" здесь

Надеюсь, это поможет.