Задачи prototypejs от 1.6 до 1.7 - PullRequest
       2

Задачи prototypejs от 1.6 до 1.7

0 голосов
/ 12 февраля 2011

У меня была проблема с анализом json при обновлении моего приложения с прототипа 1.6.1 до 1.7.0. Это очень упрощенная модель моего json, сохраненная в tmp.js:

{
"text":"hello world",
"fn": function(){alert('hello world')
}

, и этомой код:

new Ajax.Request('tmp.js', {
onSuccess: function(transport){
    var json = transport.responseText.evalJSON();

    var button = new Element('button')
            .update(json.text)
        .observe('click', function(){
            json.fn();
        });
    $('my_div').update(button);
}});

Все это правильно работало с 1.6.1: он выдавал кнопку, которая предупреждала «привет мир» при нажатии.Это не работает в v. 1.7.0, из-за того, что мой json недействителен.Я знаю, что он не должен содержать функции, а только данные.

Мой вопрос: почему он работал с 1.6.1 (и до сих пор работает) и есть ли способ сделать то же самое с 1.7.0.Мне нужно получить через ajax объект js, содержащий определенные пользователем функции.

Спасибо

Обновление : функция реконструкции - хорошее решение, и я думаю, что я буду использоватьэто в будущем.В любом случае, я нашел функцию eval (), которая кажется хорошим и быстрым решением:

tp.js JSON:

{
"text":"hello world",
"fn": "my_alert('hello world')"
}

JS

function my_alert(string){
    alert(string);
}

new Ajax.Request('tmp.js', {
onSuccess: function(transport){
    var json = transport.responseText.evalJSON();

    var button = new Element('button')
            .update(json.text)
        .observe('click', function(){
            eval(json.fn);
        });
    $('my_div').update(button);
}});

1 Ответ

1 голос
/ 12 февраля 2011

То, что вы получили в этих образцах данных, вы разместили , а не JSON. В строгом JSON значение свойства может быть

  • строка
  • число
  • логическое true или false
  • null
  • массив
  • объект

Нет способа включить определение функции в JSON. (Ну, это не совсем так; вы можете использовать строки, числа, массивы, объекты и т. Д. Для описания функции таким образом, что ваш код может восстановить ее после анализа JSON. Дело в том, что прямые выражения функций JavaScript запрещены.)

Одна простая, слегка мешающая вещь, которую вы можете сделать, это сохранить тело функции в виде строки, а затем восстановить ее, вызвав

foo.fn = new Function(foo.fn);

после завершения анализа JSON.

редактировать подробнее:

Конструктор «Function ()» принимает в качестве аргументов список строк, представляющих имена аргументов, за которыми следует строка, которая будет использоваться в качестве тела функции. Если вы хотите закодировать полную функцию JavaScript, вы можете захотеть, чтобы она выглядела как объект:

{
  'foo': 'plain property',
  'someFunction': {
    'arguments': [ 'x', 'y' ],
    'body': 'if (x > y) return "x"; return "y";'
  }
}

Теперь, чтобы превратить someFunction в real функцию, вы должны использовать что-то вроде этого:

function reconstructFunction(descr) {
  var params = (descr.arguments || []).slice(0);
  params.push(descr.body);
  return Function.apply(null, params);
}

Затем вы можете просто передать дескриптор функции из вашего JSON во что-то в этом роде, и тогда у вас будет истинная функция JavaScript для вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...