Вам нужно отвязать $scope. $On в $scope $destroy event?

У меня есть директива о том, что событие привязки с использованием $on нужно удалить эту привязку, когда область действия уничтожена, или она выполняется автоматически? Также мне нужно вызвать $element.off?

return {
    restrict: 'A',
    link: function($scope, $element, $attrs) {
        $element.on('load', function() {
            $element[0].contentWindow.focus();
        });
        $scope.$on('iframe:focus', function() {
            $element[0].contentWindow.focus();
        });
    }
};

Ответ 1

$scope.$on() listenerers будут автоматически уничтожены/очищены, если теряет свое представление из-за привязки E2E в вашем представлении. Обратите внимание, что это не произойдет для привязок $rootScope.$on(). Вы также можете взглянуть на документацию $scope of AngularJS.

Ответ в нескольких словах:

  • $scope.$on(); будет автоматически уничтожен.
  • Вам нужно уничтожить $rootScope.$on() вручную.

В документе говорится:

Разрушение области - когда области содержимого больше не нужны, это ответственность создателя детского пространства, чтобы уничтожить их через scope. $destroy() API. Это делается для того, чтобы прекратить распространение $digest вызывает дочернюю область и позволяет использовать память, используемую модели детского прицела, подлежащие возврату сборщиком мусора.

Пример того, как уничтожить $rootScope.$on():

//bind event
var registerScope = $rootScope.$on('someEvent', function(event) {
    console.log("fired");
});

// clean up
$scope.$on('$destroy', registerScope);

Этот plnkr покажет вам различные типы поведения $scope.$on() и $rootScope.$on().

Переключив представление в этом plunkr, контроллер будет переподтвержден к вашему представлению. Событие $rootScope.$on(); привязывается при каждом переключении вида, не уничтожая привязки событий в представлении раньше. Таким образом, слушатели $rootScope.$on() будут сложены/умножены. Это не произойдет с привязками $scope.$on(), потому что он будет уничтожен путем переключения представления (потеряв представление привязки E2E в DOM).


Обратите внимание, что:

  • $scope.$on('event'); будет слушать $scope.$broadcast('event') и $rootScope.$broadcast('event')

  • $rootScope.$on('event'); будет слушать только $rootScope.$broadcast('event')

Ответ 2

Нет, вам не нужно удалять эту привязку. Он будет удален, когда область будет уничтожена. Однако, если вы привязываете событие к $rootScope, всегда помните, чтобы отвязать его! Это можно сделать так:

        var unregister = $rootScope.$on('eventName', function(e) {
            //doSomething
        });


        $scope.$on('$destroy', unregister);

Ответ 3

Разрушение области - когда области содержимого больше не нужны, это ответственность создателя детского пространства, чтобы уничтожить их через сфера. $уничтожить() API. Это делается для того, чтобы прекратить распространение $digest вызывает дочернюю область и позволяет использовать память, используемую модели детского прицела, подлежащие возврату сборщиком мусора.

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

Когда выполняется $scope.$destroy(), он удалит всех слушателей, зарегистрированных через $on , на $scope. Он не будет удалять элементы DOM или любые прикрепленные обработчики событий, добавленные через:

element.on('click', function (event) {
  ...
});

Дополнительная информация о angular.element https://docs.angularjs.org/api/ng/function/angular.element

Ответ 4

Мне нужно удалить эту привязку, когда область действия уничтожена,

Слушатели автоматически удаляются путем повторной инициализации $$listeners. Вот соответствующая часть из исходного кода:

  $destroy: function() {
    ...
    // Disable listeners, watchers and apply/digest methods
    this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop;
    this.$on = this.$watch = this.$watchGroup = function() { return noop; };
    this.$$listeners = {};
    ^^^^^^^^^^^^^^^^^^^

Также мне нужно вызвать $element.off?

Нет, они должны быть удалены браузером, когда DOM node, связанный с $element, будет уничтожен.