Вам нужно отменить привязку $scope.$ On к событию $scope $destroy?

У меня есть директива о событии связывания с использованием $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();
        });
    }
};

4 ответа

Решение

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

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

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

Документация гласит:

Разрушение области - когда дочерние области больше не нужны, создатель дочерней области несет ответственность за их уничтожение с помощью API scope. $ Destroy (). Это сделано для того, чтобы остановить распространение вызовов $ 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(),

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


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

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

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

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

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


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

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

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

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

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

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

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

Слушатели удаляются автоматически путем повторной инициализации $$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 связан с $element уничтожен

Другие вопросы по тегам