Automatically register trigger callbacks for selected methods in Javascript
-
16-06-2021 - |
Frage
I need to be able to expose one object's methods to be called by event triggers. I also want to register these triggers automatically by providing a list of methods and their arguments for a given object. Here is what I have (jsfiddle here):
function A() {
}
A.prototype = {
register: function(cbname, cbargs, context) {
args = ['context'].concat(cbargs);
var callback = new Function(args, "context." + cbname + "(" + cbargs.toString() + ");");
$(document).bind(cbname, callback);
document.write(callback.toString() + "<br />");
}
};
function B() {
}
B.prototype = {
add: function(l, r) {
document.write(l + r);
}
};
$(function() {
var a = new A();
var b = new B();
a.register('add', ['l', 'r'], b);
$(document).trigger('add', [b, 1, 2]);
});
The created callback has what seems to be the correct code: function anonymous(context,l,r) { context.add(l,r); }
but when ran I get the error message in console saying Uncaught TypeError: Object #<Object> has no method 'add'
. What am I doing wrong?
Lösung
var callback = new Function(args, "context." + cbname + "(" + cbargs.toString() + ");");
Functions created with the Function constructor do not create closures to their creation contexts; they always run in the window context. And it's a form of eval, so it's better to avoid at all cost.
function A() {}
A.prototype = {
register: function (name, context) {
var callback = function () {
var args = Array.prototype.slice.call(arguments);
args.shift();
context[name].apply(context, args);
};
$(document).bind(name, callback);
}
};
function B() {}
B.prototype = {
add: function (l, r) {
console.log(l + r);
}
};
var a = new A(),
b = new B();
a.register('add', b);
$(document).trigger('add', [2, 3]); // 5
Andere Tipps
I believe the first argument of a triggered event is the event itself.
So I think you'd need to change the line in your register function as follows:
args = ['evt', 'context'].concat(cbargs);
(jsFiddle: http://jsfiddle.net/hVGcE/3/)