2016-03-25 5 views
0

Я потратил больше времени, чтобы понять, почему экземпляр класса после удаления директивы не уничтожает. Я написал следующий код. Пожалуйста, помогите мне решить проблему. Код приведен ниже. Результат в журнале консоли!Почему после удаления директивы «человек» экземпляр класса все еще существует?

'use strict'; 
 

 
var app = angular.module('app', []); 
 
app.controller('mainController', function($scope, Service) { 
 
    $scope.service = Service; 
 

 
    $scope.checkAll = function() { 
 
     $scope.service.triggerListener('update'); 
 
    }; 
 

 
    $scope.add = function() { 
 
     $scope.count.push({}); 
 
    }; 
 

 
    $scope.object = { 
 
     updateAll: function() { 
 
      console.log('Count of directive "person"'); 
 
     } 
 
    }; 
 

 
    $scope.removeElement = function() { 
 
     $scope.count.splice(0, 1); 
 
    }; 
 

 
    $scope.count = [0, 1, 2, 3, 4]; 
 
}); 
 
app.service('Service', function() { 
 
    this.listeners = []; 
 

 
    this.addListeners = function (object, event, callback) { 
 
     if (!this.listeners.hasOwnProperty(event)) { 
 
      this.listeners[event] = []; 
 
     } 
 
     this.listeners[event].push(object[callback]); 
 
    }; 
 

 
    this.triggerListener = function(event) { 
 
     if (this.listeners.hasOwnProperty(event)) { 
 
      for (var i = 0; i < this.listeners[event].length; i++) { 
 
       this.listeners[event][i](); 
 
      } 
 
     } 
 
    }; 
 
}); 
 
app.directive('person', function() { 
 
    var directive = { 
 
     restrict: 'E', 
 
     template: '<button id="{{vm.index}}">Person</button> ' + 
 
        '<button ng-click="vm.add(index)">add</button>' + 
 
        '<button ng-click="vm.removeElement(index)">Clear</button>', 
 
     scope: { 
 
      index: '=', 
 
      service: '=', 
 
      removeElement: '&', 
 
      object: '=', 
 
      add: '&' 
 
     }, 
 
     controller: function() { 
 

 
     }, 
 
     link: function (scope) { 
 
      scope.vm.service.addListeners(scope.vm.object, 'update', 'updateAll'); 
 
     }, 
 
     controllerAs: 'vm', 
 
     bindToController: true 
 

 
    }; 
 

 
    return directive; 
 
});
<!DOCTYPE html> 
 
<html lang="en" ng-app="app"> 
 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title></title> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.2/angular.min.js"></script> 
 
    <script src="script.js"></script> 
 
</head> 
 
<body ng-controller="mainController"> 
 
<div ng-repeat="item in count"> 
 
    <person add="add()" index="$index" service="service" object="object" remove-element="removeElement()" show="show()">{{$index}}</person> 
 
</div> 
 
<button ng-click="checkAll()">Count of "person" directive</button> 
 
</body> 
 
</html>

+0

Потому что вы добавляете только слушателей, но не удаляете их. –

+0

Ваш метод 'removeElement()' не удаляет ваши слушатели. Удаление элемента dom или элемента массива 'count' не имеет ничего общего с тем, что хранится в массиве службы' listeners' – charlietfl

ответ

0

Ваша директива только добавляет listeners массив ... но нет ничего в вашем коде, чтобы удалить что-нибудь из этого массива

Вам нужен removeListener метод, который будет называться в методе removeElement.

$scope.removeElement = function() { 
     var index = // get index of element 
     $scope.count.splice(index, 1); 

     Service.removeListener(index); 
}; 

В службе:

this.removeListener = function(index){ 
    this.listeners.splice(index,1); 
}; 

В качестве альтернативы можно использовать $destroy событие в директиве:

link: function (scope) { 
     Service.addListeners(scope.vm.object, 'update', 'updateAll'); 
     scope.$on('$destroy', function(){ 
      Service.removeListener(scope.index); 
     }); 
}, 

Обратите внимание, что инъекционные Service в директиве проще и чище, чем прохождение через HTML атрибуты сфера охвата

app.directive('person', function(Service) { 
Смежные вопросы