2016-07-03 2 views
0

Как правильно обрабатывать события (например, $rootScope или события сокета) в угловом контроллере? Я столкнулся с проблемой, что мои контроллеры не уничтожены, что вызывает некоторые проблемы, когда дело доходит до прослушивания определенных событий.Время работы и время обработки углового контроллера

Для того, чтобы понять, что я имею в виду вот plunker: http://plnkr.co/edit/CkXKUnpUdsbnZEjq8zLy?p=preview

Инициирование событие rootscope (нажав на кнопку), в первую очередь работает как задумано: только одно событие забирается. Но переход к Route 2 и запуск события корнеплодов снова показывает мою проблему; событие извлекается дважды, поскольку (по крайней мере, это мое предположение) оба контроллера активны сейчас. Каждый переключатель маршрута вызывает дополнительный прослушиватель событий.

Как с этим справиться?

ответ

1

Используйте $scope.$on вместо $rootScope.$on, слушатели будут автоматически уничтожены при уничтожении области.

+0

Хорошо, это очень помогает, спасибо. Осталось только одна проблема: значит ли это такие вещи, как события сокета ('socket.on ('event', ...)'), необходимо разместить внутри службы и никогда в контроллере? Поскольку прослушивание событий сокетов ведет себя так же, как прослушивание на событии '$ rootScope', его можно запускать несколько раз. – nehalist

1

Ответ, данный JosselinTD, является правильным. Если событие транслируется на $ rootScope, достаточно прослушивать его в $ scope вашего соответствующего контроллера, поскольку трансляция запускается во всех областях, которые иерархически ниже области действия, на которой запускается событие, и все остальные области находятся где-то ниже $ rootScope ,

Если это не вариант, например. потому что вы хотите поймать событие, которое испускается (используя метод $ emit вместо $ broadcast) и не пропускает ваш $ scope, вы также можете прослушивать $ rootScope. В этом случае вы должны убедиться, что, однако, что слушатель очистится, когда сфера вашего контроллера разрушается:

var removeListener = $rootScope.$on('yourEvent', function(event) { 
    // do what you want here.. 
}); 
// remove the listener on $rootScope when $scope is cleaned up 
// this makes sure we have no unwanted references.. 
$scope.$on('$destroy', removeListener); 

в $ по методу возвращает функцию, которая позволяет удалить слушатель, созданную ею. AngularJS вызовет событие $ destroy в вашей области $, когда контроллер будет уничтожен (например, потому что его представление заменено чем-то другим).

Если вы слушаете, не угловатыми-событий в контроллере, вы должны также использовать

$scope.$on('$destroy', function() { 
    //TODO: call some clean-up function to remove your event listener 
}); 

Это может быть удаление слушателя, как описано в socket io listener removal (stackoverflow)

Другой намек, что может быть полезно: Если вы слушаете события, происходящие вне вашего контекста AngularJS (что относится, например, к событиям DOM, но, конечно же, к событиям socket.io), вам придется обернуть их в область $ scope. $ Apply, поскольку AngularJS иначе не будет знать любых изменений, внесенных слушателем события.

socket.on('someSocketEvent', function(data) { 
    $scope.$apply(function() { 
    $scope.dataFromSocket = data; 
    }); 
});