【问题标题】:Angular.js: How can I avoid caching services?Angular.js:如何避免缓存服务?
【发布时间】:2013-04-30 00:50:44
【问题描述】:

我有一项服务将我的客户端连接到 Socket.io 服务器:

var serviceSocketIo = angular.module('myApp.services', []);

serviceSocketIo.factory('mySocket',['$rootScope', '$routeParams', function ($rootScope, $routeParams) {
  var base = $rootScope.base, //base = 'http://localhost:3000'
  channel = '/' + $routeParams.game,
  url = base + channel,
  mySocket;

  console.log('service: connection to ' + url);
  mySocket = io.connect(url);
  return {
    base: base,
    channel: channel,
    socket: mySocket,
    on: function (eventName, callback) {
      mySocket.on(eventName, function () {  
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(mySocket, args);
        });
      });
    },
    emit: function (eventName, data, callback) {
      mySocket.emit(eventName, data, function () {
        var args = arguments;
        $rootScope.$apply(function () {
          if (callback) {
            callback.apply(mySocket, args);
          }
        });
      })
    }
  };
}]);

请注意,命名空间取决于 $routePrams 参数。

我需要在实例化之前从缓存中删除服务。所以我会确保这些服务会将客户端连接到正确的 url。或者是否有其他方法可以强制我的服务检查参数?

【问题讨论】:

    标签: javascript angularjs socket.io


    【解决方案1】:

    Angular 中的工厂和服务是单例的,没有其他配置可以使它们成为一体。如果你想要这样的控制,你需要在 $provide 对象上使用方法:

    使用 app.config 获取访问权限:

    app.config(function($provide) {
       // Now you have provide 
    });
    

    您可以使用从 $get 返回的内容创建您自己的自定义实例化策略:

    $provide.provider('foo', function(){
      this.$get = function(dep) {...}
    });
    

    参考:http://slides.wesalvaro.com/20121113/#/2/6

    【讨论】:

    • 谢谢。幻灯片很有帮助。
    【解决方案2】:

    是什么让您无法创建为您创建套接字的服务?

    var services = angular.module('myApp.services', []);
    
    services.service('SocketService', function () {
        var SocketService = function () {
            this.createSocket = function (url) {
                return io.connect(url);
            }
        };
    
        return SocketService;
    });
    

    【讨论】:

    • 谢谢,我尝试过类似的方法,但使用工厂,它可以工作。
    【解决方案3】:

    服务/工厂方法只运行一次,然后使用返回值。如果要自定义返回的功能,请将这些作为参数放在返回的函数成员中。例如注意你的Arg:

    var serviceSocketIo = angular.module('myApp.services', []);
    
    serviceSocketIo.factory('mySocket',['$rootScope', '$routeParams', function ($rootScope, $routeParams) {
      var base = $rootScope.base, //base = 'http://localhost:3000'
      channel = '/' + $routeParams.game,
      url = base + channel,
      mySocket;
    
      console.log('service: connection to ' + url);
      mySocket = io.connect(url);
      return {
        base: base,
        channel: channel,
        socket: mySocket,
        // Notice yourArg 
        on: function (eventName, callback, yourArg) {
          // Use yourArg to customize behaviour: 
          mySocket.on(eventName, function () {  
            var args = arguments;
            $rootScope.$apply(function () {
              callback.apply(mySocket, args);
            });
          });
        },
        emit: function (eventName, data, callback) {
          mySocket.emit(eventName, data, function () {
            var args = arguments;
            $rootScope.$apply(function () {
              if (callback) {
                callback.apply(mySocket, args);
              }
            });
          })
        }
      };
    }]);
    

    【讨论】:

    • 恐怕这个解决方案帮不了我,让我再解释一下我的问题:我将我的服务注入两个不同的控制器,所以当我加入一个相对于例如第一个的路由时控制器,当然我的服务正在将我连接到与此路由相关的命名空间,但如果我更改路由,我的服务仍将我连接到相同的路由。这是因为,正如您所说,服务/工厂方法只运行一次,因此它们被缓存。而且我不知道如何避免这种行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    相关资源
    最近更新 更多