我有一个带有$ q.notify(..)回调的控制器,由SocketService使用。
SocketService.receive().then(null, null, function (data) {
console.log('Received data from service');
});
我预计在销毁控制器时将删除此回调。但行为是不同的。例如,如果我正在查看此控制器并且我将路由更改为不同(控制器被销毁),然后在下一个SocketService $ q.notify上返回(第二个启动控制器),则此回调将被触发2次。
[Controller-1] init
[SocketService] Received event
[Controller-1] Received data from service
[Controller-1] $on $destroy
[Controller-2] init
[Controller-2] $on $destroy
[Controller-1] init
[SocketService] Received event
2x[Controller-1] Received data from service
SocketService
var listener = $q.defer();
receive: function () {
return listener.promise;
},
socket.stomp.subscribe(TOPIC, function (data) {
console.log('[SocketService] Received event ');
listener.notify(JSON.parse(data.body));
});
如何使用controller destroy删除侦听器回调?
答案 0 :(得分:2)
将onProgress函数附加到可以取消的本地defer()
对象。
var localDefer = $q.defer();
SocketService.receive().then(null, null, function onProgress(data) {
localDefer.notify(data);
});
//use local promise
localDefer.promise.then(null, null, function onProgress(data) {
console.log('Received data from service');
});
当范围被销毁时,拒绝(或解决)本地defer()
对象以停止本地通知
$scope.$on("$destroy", function() {
localDefer.reject("scope destroyed");
});
一旦承诺得到解决(已履行或已拒绝),将忽略对defer()
方法(.resolve
,.reject
和.notify
)的进一步调用。
答案 1 :(得分:0)
该问题根本与$q
无关,它与套接字上的侦听器有关。当控制器破坏其范围时,监听器没有被删除。我们需要手动完成此过程。
$scope.$on('$destroy', function (event) {
socket.removeAllListeners(); //will remove out all the listners
});
但我认为,在您的情况下,您正在订阅活动,因此您需要在破坏范围的同时执行.unsubscribe
该事件。
socket.stomp.unsubscribe();