控制器销毁后,$ q notfy listener未被删除

时间:2016-02-17 21:10:59

标签: angularjs

我有一个带有$ 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删除侦听器回调?

2 个答案:

答案 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();