jQuery SignalR客户端.off()函数仅删除上次注册的回调 [英] jQuery SignalR client .off() function only removes last registered callback

查看:89
本文介绍了jQuery SignalR客户端.off()函数仅删除上次注册的回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用程序中使用SignalR,以允许ASP.NET Server应用程序将数据推送到Angular SPA Web客户端.在Web应用程序中,我包含了jquery.signalR-2.2.0.js文件.我没有在http(s)://serverurl/signalr/hubs上使用自动生成的代理.

I'm using SignalR in my application to allow my ASP.NET Server application to push data to my Angular SPA web clients. In the web application i've included the jquery.signalR-2.2.0.js file. I do not use the auto generated proxy on http(s)://serverurl/signalr/hubs.

该Web应用程序具有多个可重用的小部件(伪指令),每个小部件都有各自独立的作用域.同一widget/指令的多个实例需要注册一个可以由服务器的SignalR Hub执行的回调,因此我具有如下功能:

The webapplication has multiple reusable widgets (directives), each with their own isolated scope. Multiple instances of the same widget/directive need to register a callback which can be executed by the server's SignalR Hub so i have a function like this:

 var on = function (eventName, callback) {
            proxy.on(eventName, callback);
          };

此功能位于单独的服务中,该服务还具有连接和代理对象,并且到目前为止一切正常...

This function is in a seperate service which also has the connection and proxy object, and until now everything is working fine...

从负责小部件实例的角度控制器中,上面的函数被这样调用:

From a angular controller,responsible for a widget instance, the above function gets called like this:

var callback = function (){
     console.log('Callback fired on controller with Id' + $scope.id)
}

proxyHub.on('myEvent',callback);

控制器位于隔离范围内,因此var回调对于每个控制器都是不同的对象.

The controllers are in isolated scope, so the var callback is a different object for each controller.

我能够从不同的控制器中为同一事件注册多个回调,并且一切仍在按预期进行.

I am able to register multiple callbacks for the same event from different controllers, and everything is still working as expected.

现在我需要从控制器实例中注销回调,因此我在单独的服务中具有以下方法:

Now i need to unregister a callback from a controller instance, so i have the following method in my separate service:

 var off = function(eventName,callback) {
            proxy.off(eventName,callback);
        };

从这样的特定控制器实例中调用哪个:

Which gets called from a specific controller instance like this:

//callback is exactly the same variable as used in the .on function for this controller   
hubProxy.off('myevent',callback);

麻烦来了:只有最后一次注册的回调才从事件中删除.所有其他已注册的回调仍被调用.如果我尝试再次调用.off函数,则什么也没有发生,并且我无法注销其他回调.

Here comes the trouble: Only the last registered callback is removed from the event. All other registered callbacks still getting invoked. If i try to call the .off function again, nothing happens, and i am not able to unregister the other callbacks.

主要问题是:如何注销事件中的特定回调?

The main question is: How can i unregister a specific callback from an event???

推荐答案

来自

From the hubs source code it seems like it's not possible to unsubscribe multiple duplicate callbacks from a single event.

这是源代码中的 on 函数:

on: function (eventName, callback) {
        /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary>
        /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param>
        /// <param name="callback" type="Function">The callback to be invoked.</param>
        var that = this,
            callbackMap = that._.callbackMap;

        // Normalize the event name to lowercase
        eventName = eventName.toLowerCase();

        // If there is not an event registered for this callback yet we want to create its event space in the callback map.
        if (!callbackMap[eventName]) {
            callbackMap[eventName] = {};
        }

        // Map the callback to our encompassed function
        callbackMap[eventName][callback] = function (e, data) {
            callback.apply(that, data);
        };

        $(that).bind(makeEventName(eventName), callbackMap[eventName][callback]);

        return that;
    },

如您所见,"event:callback"对将保存到 callbackMap 并绑定到集线器.如果多次调用,则 callbackMap 将被相同的值覆盖,但是回调将被绑定多次.

as you can see, the "event:callback" pair is saved to callbackMap and bound to hub. If you call it multiple times, the callbackMap will be overwritten with the same value, but the callback will be bound multiple times.

off 功能中:

off: function (eventName, callback) {
        /// <summary>Removes the callback invocation request from the server hub for the given event name.</summary>
        /// <param name="eventName" type="String">The name of the hub event to unregister the callback for.</param>
        /// <param name="callback" type="Function">The callback to be invoked.</param>
        var that = this,
            callbackMap = that._.callbackMap,
            callbackSpace;

        // Normalize the event name to lowercase
        eventName = eventName.toLowerCase();

        callbackSpace = callbackMap[eventName];

        // Verify that there is an event space to unbind
        if (callbackSpace) {
            // Only unbind if there's an event bound with eventName and a callback with the specified callback
            if (callbackSpace[callback]) {
                $(that).unbind(makeEventName(eventName), callbackSpace[callback]);

                // Remove the callback from the callback map
                delete callbackSpace[callback];

                // Check if there are any members left on the event, if not we need to destroy it.
                if (!hasMembers(callbackSpace)) {
                    delete callbackMap[eventName];
                }
            } else if (!callback) { // Check if we're removing the whole event and we didn't error because of an invalid callback
                $(that).unbind(makeEventName(eventName));

                delete callbackMap[eventName];
            }
        }

        return that;
    },

在第一次调用 off 函数时,将从 callbackMap 中删除"event:callback"对,并与集线器解除绑定(一次).但是在下一次呼叫时,"event:callback"对不再存在,因此所有其他事件仍绑定到集线器.

that "event:callback" pair is removed from callbackMap on first call of the off function and unbound from hub (once). But on next call, the "event:callback" pair is not there anymore, so all other events are still bound to hub.

一种解决方案是通过仅使用 myEventName 调用 off 函数,而不指定回调来从事件中删除所有回调.但是,我不确定这是否适用于您的情况.

One solution could be to remove all callbacks from the event, by just calling off function with only myEventName, and not specifying the callback. But I'm not sure, if this is applicable in your case.

这篇关于jQuery SignalR客户端.off()函数仅删除上次注册的回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆