gpt4 book ai didi

javascript - jQuery SignalR 客户端 .off() 函数仅删除最后注册的回调

转载 作者:行者123 更新时间:2023-11-28 15:15:08 27 4
gpt4 key购买 nike

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

网络应用程序有多个可重用的小部件(指令),每个小部件都有自己独立的范围。同一小部件​​/指令的多个实例需要注册一个回调,该回调可以由服务器的 SignalR Hub 执行,因此我有一个如下所示的函数:

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

这个函数位于一个单独的服务中,它也有连接和代理对象,到目前为止一切都工作正常......

从负责小部件实例的 Angular Controller 中,上面的函数被这样调用:

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

proxyHub.on('myEvent',callback);

Controller 处于隔离范围内,因此 var 回调对于每个 Controller 来说都是不同的对象。

我能够从不同的 Controller 为同一事件注册多个回调,并且一切仍然按预期工作。

现在我需要从 Controller 实例取消注册回调,因此我在单独的服务中有以下方法:

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

从特定的 Controller 实例调用它,如下所示:

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

麻烦来了:只有最后注册的回调会从事件中删除。所有其他注册的回调仍然被调用。如果我尝试再次调用 .off 函数,则不会发生任何事情,并且我无法取消注册其他回调。

主要问题是:我如何从事件中取消注册特定回调???

最佳答案

来自hubs source code似乎无法从单个事件中取消订阅多个重复的回调。

这是源代码中的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并绑定(bind)到集线器。如果多次调用,callbackMap将被相同的值覆盖,但回调将被绑定(bind)多次。

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 函数时,该“event:callback”对会从 callbackMap 中删除,并与集线器解除绑定(bind)(一次)。但在下一次调用时,“event:callback”对不再存在,因此所有其他事件仍然绑定(bind)到集线器。

一种解决方案可能是从事件中删除所有回调,只需调用仅使用 myEventNameoff 函数,而不指定回调。但我不确定这是否适用于您的情况。

关于javascript - jQuery SignalR 客户端 .off() 函数仅删除最后注册的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34336603/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com