получить значение функции в строке json - PullRequest
1 голос
/ 23 марта 2012

Я пытаюсь заставить некоторый json содержать функцию, чтобы опция в плагине получала возвращаемое значение функции, которая была в строке json.

Настройка такова:

default.txt

    [
        {
            "element":"a[href$='.jpg']",
            "options":{
                "label":"test"
                }
        },{
            "element":"a#hover",
            "options":{
                "label":(function(ele){ return 'test'; })()
            }
        }
    ]

, а плагин -

(function($) {
    function defined(obj){return typeof(obj)!=='undefined';}
    function evaluate(ele, obj) {
        if(typeof obj === 'function') {
            //alert('is function');
            obj = obj(ele);
        }else{
            try{
                //alert('thinking it may be a function still');
                obj = eval("("+obj+"("+ele+"));"); 
                //obj = (obj)(ele);
            }catch(err){
                //Handle errors here
                //alert('not function');
            }
        }
        return obj;
    }
    function debug(message) {
          console.debug(message);
    }
    $.set = function(options){
        var settings = $.extend({}, {}, options);
        if(defined(settings.actions)){
            $.each(settings.actions, function(index, value) { 
                $(value.element).do_action(defined(value.options)?value.options:null);
            });
        }   
    }

  $.fn.do_action = function(options) {
    // Add event handler to all matching elements
    return this.each(function() {
        var ele = $(this);
            var settings = $.extend({}, $.fn.do_action.defaults, options);
            var label= evaluate(ele, settings.label);

            var message = "label:'" + label + "'";
            debug('Tracking ' + action + ' ' + message);
    });
  };
  $.fn.do_action.defaults = {
    label         : function(ele) { return ele.attr('href'); }
  };
}(jQuery));

, а элемент управления -

$.getJSON('default.txt' , function(data){
    $.set({
        actions:data // this si where we pull in the options
    });
});

Кажется, что работаетЯ вставил предупреждение в анонимную функцию, так что с

"label":(function(ele){ return 'test'; })()

до

"label":(function(ele){ alert('test') })()

, но после этого я не могу заставить его печатать прямо в консоли, когда яполучите только сообщение

Tracking label:'(function(ele){ return 'test'; })

[EDIT] Пожалуйста, перестаньте говорить, что «вы не должны вводить код в json».Если вы работаете в Google и их программистам высшего уровня платят большие супер баксы, я послушаю, почему, но извините, если это хорошо для них, это будет работать для меня.Не знаю, что еще сказать, я уже понимаю, почему вы должны избегать этого, что я и собираюсь делать.Бывают моменты, когда вы просто не можете, и я думаю, что Google делает то же самое.

1 Ответ

1 голос
/ 23 марта 2012

Ваш label член не является функцией; это значение, возвращаемое функцией. Окончательное значение () в конце означает «выполнять эту функцию немедленно, когда запрашивается значение label, и предоставлять его возвращаемое значение в качестве значения label».

Тем не менее, если вы должны включить функции в ваш объект JSON (и из того, что вы сказали, вы делаете), ваш лучший выбор - это упорядочить и оценить ваши функции. Вы также должны иметь возможность использовать необработанные функции в вашем JSON, например, {foo: (function () {...})}, хотя лично мне было непросто сделать это правильно (но это только я - если вы может сделать это правильно, пойти на это).

(Кроме того, невозможно упорядочить функции из существующих объектов, но если вы получаете ваши функции в виде текста из пользовательского / программистского ввода, это не проблема.)

...