Gal*_*aim 52 socket.io angularjs
我想在AngularJS中使用socket.io.我找到了以下工厂:
app.factory('socket', function ($rootScope) {
var socket = io.connect();
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);
}
});
})
}
};
Run Code Online (Sandbox Code Playgroud)
它在控制器中使用如:
function MyCtrl($scope, socket) {
socket.on('message', function(data) {
...
});
};
Run Code Online (Sandbox Code Playgroud)
问题是每次访问控制器时都会添加另一个侦听器,因此在收到消息时会多次处理.
什么是将socket.io与AngularJS集成的更好策略?
编辑:我知道我可以在工厂中没有返回任何内容并在那里进行监听,然后在控制器中使用$ rootScope.$ broadcast和$ scope.$ on,但它看起来不是一个好的解决方案.
EDIT2:加入工厂
init: function() {
socket.removeAllListeners();
}
Run Code Online (Sandbox Code Playgroud)
并在每个使用socket.io的控制器的开头调用它.
仍然不觉得最好的解决方案.
bml*_*ite 52
每当控制器被销毁时删除套接字侦听器.您需要绑定$destroy事件,如下所示:
function MyCtrl($scope, socket) {
socket.on('message', function(data) {
...
});
$scope.$on('$destroy', function (event) {
socket.removeAllListeners();
// or something like
// socket.removeListener(this);
});
};
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请查看angularjs文档.
您可以通过包装Scope并观察$destroy要进行广播来完成最少量的工作来处理这个问题,当它只是从套接字中删除在该Scope的上下文中添加的侦听器时.请注意:以下内容尚未经过测试 - 我认为它更像伪代码而不是实际代码.:)
// 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) {
...
});
};
Run Code Online (Sandbox Code Playgroud)
我会对接受的答案添加评论,但我不能.所以,我会写一个回复.我遇到了同样的问题,我发现的最容易和最简单的答案就是你可以在这里找到的那个,在michaeljoser提供的另一篇文章中.
为方便起见,我会在下面复制它:
您必须将removeAllListeners添加到工厂(见下文)并在每个控制器中包含以下代码:
$scope.$on('$destroy', function (event) {
socket.removeAllListeners();
});
Run Code Online (Sandbox Code Playgroud)
更新套接字工厂:
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);
});
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
它节省了我的一天,我希望它对别人有用!
| 归档时间: |
|
| 查看次数: |
28362 次 |
| 最近记录: |