Почему мои вызовы socket.on увеличиваются каждый раз, когда я перезаписываю свой контроллер
Я использовал фабрику сокетов, описанную здесь Брайаном Фордом http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/
вот фабрика myApp.factory('socket', функция ($rootScope) {
var socket = io.connect('url');
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
}
};
});
У меня есть socket.emit в моей функции инициализации контроллеров, и всякий раз, когда я повторно ввожу этот контроллер с другой страницы, получающая функция socket.on выполняется +1 раз. Это происходит до тех пор, пока я не обновлю страницу вручную, затем она сбрасывается до 1. Я явно не сохраняю свой сокет в сеансе. Так что может вызывать мой socket.on для вызова несколько раз.
Вот мой socket.emt в моем контроллере, он всегда выполняется один раз.
$scope.init = funciton (){
...
socket.emit('getSignedSlidesFromUrl', $scope.slideLocation);
}
Вот мой socket.on, который будет получать 'getSignedSlidesFromUrl'
socket.on('signedUrls', function (signedSlides){
console.log('signedUrls socket hit');
$scope.slides = signedSlides;
console.log($scope.slides[0]);
console.log($scope.display);
});
Вот пример моего журнала консоли после повторного входа в контроллер
собирается испустить getSignedSlidesFromUrl из init controllers.js:71
display after called $scope.first slide is0 controllers.js:574
flash object is controllers.js:537
signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823
если я снова введу контроллер снова, мой журнал изменится на
signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823
signedUrls socket hit controllers.js:816
0 controllers.js:823
2 ответа
Вы должны добавить removeAllListeners к вашей фабрике (см. Ниже) и иметь следующий код в каждом из ваших контроллеров:
$scope.$on('$destroy', function (event) {
socket.removeAllListeners();
});
Обновлена фабрика сокетов:
var socket = io.connect('url');
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
},
removeAllListeners: function (eventName, callback) {
socket.removeAllListeners(eventName, function() {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
}
};
});
Я попробовал решение @michaeljoser, но оно не сработало для меня.
Тогда я нашел другое решение, и оно сработало
var socket = io.connect('url');
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
},
getSocket: function(){
return socket;
}
};
});
И в контроллере я позвонил
$scope.$on('$destroy', function (event) {
socket.getSocket().removeAllListeners();
});