2016-05-07 3 views
0

У меня есть представление (я буду вызывать родителя), у которого есть другое представление внутри него (дочерний вид). Родительское представление имеет элементы, которые используют событие «контекстное меню» (при щелчке правой кнопкой мыши появляется набор параметров меню). Когда пользователь выбирает элемент из меню, он вызывает обратный вызов. Оттуда я запускаю событие в дочернем представлении. Вот мой триггер:Backbone.js ListenToOnce вызывается дважды

that.trigger("editFileFolder", {fileType: fileType}); 

В функции инициализации мой взгляд ребенка, у меня есть это:

this.listenToOnce(this.options.parent,'editFileFolder', this.editFileObjectEvent); 

Функция editFileObjectEvent вызывает другой вид, который будет создан (диалог с некоторыми полями, кнопка отмены и кнопка сохранения). Если пользователь нажимает кнопку «Отменить», все работает нормально. Если использование нажимает кнопку сохранения, представление выполняет вызов ajax, сохраняет сервер и закрывает диалоговое окно. Но в следующий раз, когда пользователь щелкает правой кнопкой мыши и выбирает один и тот же пункт меню, editFileObjectEvent вызывается дважды (в результате двойное добавление диалога к родительскому представлению).

Может ли кто-нибудь объяснить, почему это вызвано дважды и как это решить? Если вы хотите увидеть конкретный код, дайте мне знать, и я могу добавить его. Там много, поэтому я не хочу подавлять вопрос.

благодаря

+0

Я думаю, что функция, которую называют 'this.listenToOnce' вызывается дважды – andlrc

+0

хмм, кажется, что вы правы. Есть ли способ определить, есть ли этот слушатель уже на месте, поэтому я могу избежать его повторного добавления? – jason

+0

Я не думаю, что публичный API. Но вы можете взглянуть на 'this._listeningTo' – andlrc

ответ

2

Я думаю, что функция, которая вызывает this.listenToOnce вызывается дважды. Вы должны стараться избегать этого. Однако, если это не возможно, вы можете убедиться, что слушатели только обязаны один раз отменяя его перед переплетом:

this.stopListening(this.options.parent, 'editFileFolder', this.editFileObjectEvent); 
this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent); 

Или вы могли бы иметь свойство на вашем экземпляре для предотвращения связывания дважды:

if (!this.__boundListener) { 
    this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent); 
    this._boundListener = true; 
} 

Все слушатели зарегистрированы в this._listeningTo, и, возможно, вы сможете выполнить поиск, чтобы проверить, не связано ли событие.

Вы также можете реорганизовать код:

MyModel.extend({ 
    initialize: function() { 
    this.bindListenToOnce = _.once(this.bindListenToOnce); 
    }, 
    abc: function() { 
    // do stuff 
    this.bindListenToOnce(); 
    // do stuff 
    }, 
    bindListenToOnce: function() { 
    this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent); 
    } 
});