Reputation: 717
Can anyone advise me how to create a method call using a string and without using eval
? Please note that methodCall
cannot be hard-coded and has to be dynamic. methodCall
will be created dynamically.
In the following example this
refers to a Backbone view, e.g.
var amount = this.model.get('amount');
var $amount = this.$el.find('.amount');
var methodCall = 'this.parentController.parentController.addBinding';
//then need to call the method with args
methodCall('amount',$amount);
I first thought this would work:
this['controller']['parentController']['view']['addBinding'](amount, $amount);
However I came to realise that this would not be dynamic either. Does anyone have a solution?
Upvotes: 2
Views: 323
Reputation: 33364
As noted in this answer, Multiple level attribute retrieval using array notation from a JSON object, you can traverse the hierarchy of objects with something like this:
function findprop(obj, path) {
var args = path.split('.'), i, l;
for (i=0, l=args.length; i<l; i++) {
if (!obj.hasOwnProperty(args[i]))
return;
obj = obj[args[i]];
}
return obj;
}
You could then give your view/model/collection a method to apply an arbitrary path:
var V = Backbone.View.extend({
dyncall: function(path) {
var f = findprop(this, path);
if (_.isFunction(f))
return f.call(this, 'your args');
}
});
var v = new V();
v.dyncall('parentController.parentController.addBinding');
And a demo http://jsfiddle.net/nikoshr/RweEC/
A little more flexibility on passing the arguments :
var V = Backbone.View.extend({
dyncall: function() {
var f = findprop(this, arguments[0]);
if (_.isFunction(f))
f.apply(this, _.rest(arguments, 1));
}
});
var v = new V();
v.dyncall('parentController.parentController.addBinding', 'your arguments', 'another arg');
http://jsfiddle.net/nikoshr/RweEC/1/
Upvotes: 2