Подтвердить что ты не робот

Почему не запускается $destroy, когда я вызываю element.remove?

Я не могу понять, почему событие $destroy не запускается в следующем примере. Может кто-нибудь объяснить, почему он не срабатывает, и в каких сценариях он будет запущен?

Здесь plunkr: http://plnkr.co/edit/3Fz50aNeuculWKJ22iAX?p=preview

JS

angular.module('testMod', [])
.controller('testCtrl', function($scope){
  $scope.removeElem = function(id) {
    var elem = document.getElementById(id);
    angular.element(elem).remove();
  }
}).directive('testDir',[function() {
  return {
    scope:true,
    link: function(scope) {
      console.log('in directive');
      scope.$on('$destroy', function(){
        alert('destroyed');
      })
    }
  }
}]);

HTML

<body ng-controller='testCtrl'>
  <div testDir id='test'>I will be removed.</div>
  <button ng-click='removeElem('test')'>remove</button>
</body>
4b9b3361

Ответ 1

Проблема заключается в том, что вы слушаете событие $destroy на scope, но $destroy запускается на element.

Из источника angular.js(я уверен, что он где-то документально оформлен на веб-сайте, но я не смотрел):

$destroy - AngularJS перехватывает все уничтожение DOM jqLite/jQuery apis и запускает это событие на всех удаленных узлах DOM. Это может использоваться для очистки любых сторонних привязок к элементу DOM до он удаляется.

Ваша директива должна быть (обратите внимание, что я добавил scope, element и attrs как link аргументы): Кроме того, здесь plunker.

directive('testDir',[function() {
  return {
    scope:true,
    link: function(scope,element,attrs) {
      console.log('in directive');
      element.on('$destroy', function(){
        alert('destroyed');
      })
    }
  };
}]);

Ответ 2

Я озадачен тем, почему событие $destroy не запускается при методе remove().

В соответствии с документами событие $destroy запускается в двух случаях.

  • Перед тем, как область будет уничтожена
  • Перед удалением элемента из DOM

Цель - "очистка". Вы можете прослушивать событие $destroy и выполнять необходимые очистки, прежде чем разрешить уничтожить область или элемент. ngIf, ngSwitch, ngRepeat и другие встроенные директивы/методы используют событие $destroy для выполнения очистки.

Лучшим примером может служить директива ngRepeat

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js

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

ngRepeat $destroy Пример Plunk - http://goo.gl/mkozCY