Backbonejs:.on vs .listenTo vs .bind

Каковы различия между .on,. listenTo и .bind?

Я тестировал их здесь, и они, похоже, делают одно и то же: обратный вызов.

var NewStatusView = Backbone.View.extend({

    events: {
        "submit form": "addStatus"
    },

    initialize: function(options) {

        // using .on
        //this.collection.on("add", this.clearInput, this);

        // or using bind: 
        //_.bindAll(this, 'addStatus', 'clearInput');
        //this.collection.bind('add', this.clearInput);

        // or using listenTo: 
         _.bindAll(this, 'addStatus', 'clearInput');
        this.listenTo(this.collection, 'add', this.clearInput) ;
    },

    addStatus: function(e) {
        e.preventDefault();
        this.collection.create({ text: this.$('textarea').val() });
    },

    clearInput: function() {
        this.$('textarea').val('');
    }
});

Когда и в сценарии использовать, что лучше?

Ответы

Ответ 1

Обычно лучше использовать listenTo()

Из Основы основы от Адди Османи:

Пока on() и off() добавляют обратные вызовы непосредственно к наблюдаемому объекту, listenTo() указывает объекту прослушивать события на другом объекте, позволяя слушателю отслеживать события, для которых он прослушивания. stopListening() можно впоследствии вызвать на слушателя чтобы остановить прослушивание событий:

var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var c = _.extend({}, Backbone.Events);

// add listeners to A for events on B and C
a.listenTo(b, 'anything', function(event){ console.log("anything happened"); });
a.listenTo(c, 'everything', function(event){ console.log("everything happened"); });

// trigger an event
b.trigger('anything'); // logs: anything happened

// stop listening
a.stopListening();

// A does not receive these events
b.trigger('anything');
c.trigger('everything');

Если вы используете и выключаете и удаляете представления и их соответствующие модели в то же время, как правило, проблем нет. Но проблема возникает, когда вы удаляете представление, зарегистрированное для уведомления о события на модели, но вы не удаляете модель или не вызываете удалить обработчик событий views. Поскольку модель имеет ссылку на функция обратного вызова вида, сборщик мусора JavaScript не может удалить вид из памяти. Это называется призракным видом и является формой утечки памяти, что является обычным явлением, поскольку модели обычно имеют тенденцию пережить соответствующие представления во время жизненного цикла приложений. Для подробную информацию о теме и решении, проверьте эту замечательную статью на Дерик Бэйли.

Практически каждый вызываемый объект on требует также offчтобы сборщик мусора выполнял свою работу. listenTo()изменения, позволяющие представлениям привязываться к уведомлениям модели и отменить привязку из всех них одним звонком - stopListening().

Реализация по умолчанию View.remove() выполняет вызов stopListening(), гарантируя, что любые слушатели, связанные с использованием listenTo()не связаны до того, как будет уничтожено представление.

var view = new Backbone.View();
var b = _.extend({}, Backbone.Events);

view.listenTo(b, 'all', function(){ console.log(true); });
b.trigger('anything');  // logs: true

view.listenTo(b, 'all', function(){ console.log(false); });
view.remove(); // stopListening() implicitly called
b.trigger('anything');  // does not log anything