Почему мои вызовы 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();
        });
Другие вопросы по тегам