我已经使用 jQuery 事件完成了一些发布/订阅。
基本功能有效:
var publish = function(name) { // --- works
var args = Array.prototype.slice.call(arguments); // convert to array
args = args.slice(1); // remove arg1 (name)
$("html").trigger(name, args);
}
var subscribe = function(name, callback) { // --- works
$("html").on(name, callback);
}
var unsubscribe = function(name, callback) { // --- works
$("html").off(name, callback);
}
// usage: // --- works
var myhandler = function () { /* ... */ };
subscribe("foo", myhandler);
publish("foo", 1, false, "bob", {a:1, b:"2"});
unsubscribe("foo", myhandler);
但是以我想要的方式订阅,不会:
var subscribe = function(name, callback) { // --- can't unsub this
$("html").on(name, function () {
var args = Array.prototype.slice.call(arguments);
args = args.slice(1);
callback.apply(null, args);
});
}
我要第二个subscribe
函数,因为匿名回调去除了第一个参数(Event
对象),我不希望在“干净”的客户端代码中使用它。我只想在回调中接收事件数据,我不需要事件对象本身。
但这意味着我不能调用 unsubscribe
成功,因为我没有进入 off()
与传入 on()
相同的回调- 这不是实际的回调,而是一个包装的匿名函数。
有解决办法吗?
最佳答案
通常的方法是使用 jQuery 的 "namespaced" events :
$("html").on(name + ".my-pub-sub", function () {
// ...
});
然后取消订阅:
$("html").off(name + ".my-pub-sub");
这告诉 jQuery 删除所有具有给定事件名称和特定命名空间的处理程序。
这是一个简化的例子:
// Add two click handlers:
$("button").on("click", function() {
$("<p>Non-namespaced click</p>").appendTo(document.body);
});
$("button").on("click.namespace", function() {
$("<p>Namespaced click</p>").appendTo(document.body);
});
// Show they both trigger
$("<p>Clicking...</p>").appendTo(document.body);
$("button").click();
// Remove the namespaced one without a function ref
$("button").off("click.namespace");
// Now just the non-namespaced one runs
$("<p>Clicking again...</p>").appendTo(document.body);
$("button").click();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button>The button</button>
关于javascript - 删除 "wrapped"事件处理程序以用于发布/订阅消息传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26324516/