2017-01-03 7 views
1

Я работаю для приложения, и я хочу обмениваться угловыми js с третьей библиотекой js. Для этого я использовал метод pubsub с использованием медиатора js. Но из-за этого, когда я подписываюсь на какое-либо событие, он подписывается несколько раз, и из-за этого, когда я публикую событие, он срабатывает несколько раз.Угловые js подписываются несколько раз и запускают несколько событий

Я использовал ниже код:

angular.module('app') 
    .service('mediator', function() { 
    var mediator = window.mediator || new Mediator(); 
    return mediator; 
}); 

// Main controller begins here 
    angular.module('app').controller('MainController', MainController); 
    MainController.$inject = ['mediator']; 

    function MainController(mediator){ 
    var vm = this; 
    vm.title = "This is main controller." 

    vm.sendMessage = function(){ 
     mediator.publish('something', { data: 'Some data' }); 
    } 


    } 


    // First page controller begins here 
    angular.module('app').controller('FirstController', FirstController); 
    FirstController.$inject = ['mediator']; 

    function FirstController(mediator){ 
    var vm = this; 

    console.log('Subscribed events for first controller.'); 

    var counter = 0; 
    mediator.subscribe('something', function(data){ 
     console.log('Fired event for '+ counter.toString()); 
     counter = counter + 1; 
    }); 

    } 

Вот plunker для лучшего объяснения: Plunkr

Чтобы проверить эту plunker:

  1. Run plunker.
  2. Открытая консоль разработчика.
  3. Нажмите на первой странице
  4. Нажмите огонь событие
  5. Нажмите на второй странице
  6. Нажмите на первой странице
  7. Нажмите на огонь событие

Как перейти на первую страницу второй раз, его снова подпишутся на мероприятие и будут стрелять дважды. Это будет подписано несколько раз, когда вы переходите на первую страницу несколько раз.

Пожалуйста, дайте мне знать, если я делаю что-то неправильно.

+0

вы в настоящее время подписываетесь каждый раз, когда загружается контроллер, который будет при каждом переходе на страницу. Это похоже на простой случай отслеживания, если вы подписаны или нет, и используете 'if (! Подписанный)' или аналогичный. – Claies

+1

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

+0

@JBNizet: Можете ли вы сообщить нам, как отменить подписку на событие, используя медиатор js? –

ответ

1

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

Чтобы сделать это с помощью посредника, в первую очередь необходимо сохранить абонентскую функцию:

var sub = function(data){ 
    console.log('Fired event for '+ counter.toString()); 
    counter = counter + 1; 
} 
mediator.subscribe('something', sub); 

Затем вы можете использовать угловое событие отписаться от уведомлений, когда контроллер будет удален:

$scope.$on("$destroy", function() { 
    mediator.remove("something", sub); 
}); 

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

Не забывайте, что вы также должны вводить $ объем (даже если не использовать его в качестве держателя модели, это прекрасно, чтобы использовать его для регистрации слушателей событий): пример

angular.module('app').controller('FirstController', FirstController); 
FirstController.$inject = ['mediator', '$scope']; 

Plunkr: https://plnkr.co/edit/CgYLLSxGF2Fww5vBB7PB

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

+0

Я не хочу использовать $ scope в своем коде. Есть ли какой-либо выход с использованием объекта модели просмотра (vm)? –

+0

Почему бы и нет? Я не уверен, что есть прямой способ зарегистрировать слушателей для событий VM без $ scope, так как нет прямого способа просмотра изменений модели без $ scope. Опять же, даже если вы используете контроллер, как рекомендовал шаблон, по-прежнему есть область, за которой управляется угловой. $ scope отлично подходит для вещей, упомянутых выше. –