fernando
fernando

Reputation: 717

How to create a method call from a string without using eval

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

Answers (1)

nikoshr
nikoshr

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

Related Questions