2016-09-23 1 views
0

Я добавляю слушателя событий каждый раз, когда создаю угловой контроллер. Каждый раз, когда я покидаю эту страницу и возвращаюсь к ней, появляется новый прослушиватель событий, потому что конструктор снова вызывается.Функция JavaScript получает многократно повторяющееся событие при прослушивании событий, хотя я ссылаюсь на функцию

Когда это событие срабатывает, одно и то же событие вызывается дважды, и если я уйду и вернусь, он будет вызван 3 раза ... и т. Д. Я хочу, чтобы он всегда вызывался один раз.

Вот код для добавления слушателя событий, а функция Слушатель он называет: (FYI Я использую машинопись)

В конструкторе:

this.$window.addEventListener("message", this.processApi, false); 

Function Вызывается:

processApi = (e) => { 
    this.processApiMessage(e.data); 
}; 

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

Когда я делаю инструменты разработчика в хроме и перехожу к EventListners и перехожу в раздел сообщений, каждый раз, когда я нажимаю на конструктор, я вижу новый элемент Window. Я могу удалить каждый из EventListers с помощью инструментов разработчика, но не могу заставить его работать через код, когда я делаю:

this.$window.removeEventListener("message", this.processApi, false); 

Я обнаружил, что если я обновить страницу, все слушатели событий ясно и мой в конструкторе создан так, что он отлично работает.

Я использую угловую систему и использовал службу определения местоположения $, чтобы перейти к URL-адресу, который попал в мой контроллер, поэтому быстрым решением было заменить $ location.url ("url") на window.location.href ("url")

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

+0

Это красота Углового, это все испортит, потому что на самом деле оно не перенаправлено, оно просто меняет «взгляды». Вероятно, вы хотите установить обработчик событий в '$ rootScope' или удалить обработчик событий в' $ destroy' в контроллере? – adeneo

+0

Да, что это за конструктор? Откуда ему звонить? –

+0

Конструктор вызывается в сегменте маршрута (при этом используйте этот сегмент с этим контроллером). Я могу попробовать установить на rootScope, но я добавляю его через окно, потому что я общаюсь с другим окном через IFrame, используя postApi. –

ответ

3

Вам необходимо удалить прослушиватель событий, когда область составляет $destroyed. Итак, в конструкторе контроллера вам необходимо ввести объект $scope. И в конструкторе сделайте что-нибудь вроде этого:

$scope.$on('$destroy',() => 
    $window.removeEventListener("message", this.processApi)); 

Конечно, существует несколько способов создания контроллера. Наиболее распространенным (особенно если вы используете TypeScript) является создание класса для контроллера.

Я бы также подумал о том, чтобы добавить слушателя к корневому объекту вместо окна $, что является более угловым способом делать вещи. Сложив все это, это будет выглядеть так:

class MyController { 
    constructor($rootScope, $scope) { 
    'ngInject'; 

    let unsubscriber = $rootScope.$on('message', this.processApi, false);  
    $scope.$on('$destroy',() => unsubscriber()); 
    } 
    ... 
} 
+0

Я попытался удалить на уничтожение, и он все еще не работает. Я думал, что пока я ссылаюсь на одну и ту же функцию, мне даже не понадобится удалить, все они будут указывать на ту же функцию. В отладчике chrome в разделе «Слушатели событий» появляется раскрывающийся список сообщений, каждый раз, когда я нажимаю на конструктор, добавляется новое Окно, которое имеет свойство useCapture, passive и handler. Свойством обработчика является функция (e), как его регистрируется как общая функция вместо имени ссылки, которое я ему дал. –

+0

Я бы проверял, чтобы ваше событие $ destroy было поднято, когда вы думаете, что это так. В хром-отладчике установите контрольную точку внутри обработчика $ destroy. Используется ли это, когда вы думаете, что это нужно? Что такое код, который вы используете? –

+0

Я работал, спасибо, я попытался связать (это) с другим именем функции. Когда я вставлял ваш код, у меня были несоответствующие имена (this.processApi - новый, который я сделал, когда я добавил прослушиватель событий добавления). Еще раз спасибо. –

Смежные вопросы