Improve this AngularJS factory to use with socket.io

后端 未结 13 1513
你的背包
你的背包 2020-12-07 08:42

I want to use socket.io in AngularJS. I found the following factory:

app.factory(\'socket\', function ($rootScope) {
    var socket = io.connect();
    retur         


        
13条回答
  •  情话喂你
    2020-12-07 09:08

    You might be able to handle this with a minimal amount of work by wrapping up a Scope and watching for $destroy to be broadcast, and when it is, only removing from the socket the listeners that were added in the context of that Scope. Be warned: what follows hasn't been tested--I'd treat it more like pseudocode than actual code. :)

    // A ScopedSocket is an object that provides `on` and `emit` methods,
    // but keeps track of all listeners it registers on the socket.
    // A call to `removeAllListeners` will remove all listeners on the
    // socket that were created via this particular instance of ScopedSocket.
    
    var ScopedSocket = function(socket, $rootScope) {
      this.socket = socket;
      this.$rootScope = $rootScope;
      this.listeners = [];
    };
    
    ScopedSocket.prototype.removeAllListeners = function() {
      // Remove each of the stored listeners
      for(var i = 0; i < this.listeners.length; i++) {
        var details = this.listeners[i];
        this.socket.removeListener(details.event, details.fn);
      };
    };
    
    ScopedSocket.prototype.on = function(event, callback) {
      var socket = this.socket;
      var $rootScope = this.$rootScope;
    
      var wrappedCallback = function() {
        var args = arguments;
        $rootScope.$apply(function() {
          callback.apply(socket, args);
        });
      };
    
      // Store the event name and callback so we can remove it later
      this.listeners.push({event: event, fn: wrappedCallback});
    
      socket.on(event, wrappedCallback);
    };
    
    ScopedSocket.prototype.emit = function(event, data, callback) {
      var socket = this.socket;
      var $rootScope = this.$rootScope;
    
      socket.emit(event, data, function() {
        var args = arguments;
        $rootScope.$apply(function() {
          if (callback) {
            callback.apply(socket, args);
          }
        });
      });
    };
    
    app.factory('Socket', function($rootScope) {
      var socket = io.connect();
    
      // When injected into controllers, etc., Socket is a function
      // that takes a Scope and returns a ScopedSocket wrapping the
      // global Socket.IO `socket` object. When the scope is destroyed,
      // it will call `removeAllListeners` on that ScopedSocket.
      return function(scope) {
        var scopedSocket = new ScopedSocket(socket, $rootScope);
        scope.$on('$destroy', function() {
          scopedSocket.removeAllListeners();
        });
        return scopedSocket;
      };
    });
    
    function MyController($scope, Socket) {
      var socket = Socket($scope);
    
      socket.on('message', function(data) {
         ...
      });
    };
    

提交回复
热议问题