Я потратил больше времени, чтобы понять, почему экземпляр класса после удаления директивы не уничтожает. Я написал следующий код. Пожалуйста, помогите мне решить проблему. Код приведен ниже. Результат в журнале консоли!
'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>
Ваша директива добавляет только массив listeners
... но в вашем коде ничего нет, чтобы удалить что-либо из этого массива
Вам нужен метод removeListener
, который removeElement
методе 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) {
removeElement()
не удаляет ваших слушателей. Удаление элемента dom или элемента массиваcount
имеет ничего общего с тем, что хранится в массивеlisteners
службы