Создание объектов Javascript из шаблона

я хочу создать объект JavaScript из шаблона. Проблема в том, что я не знаю, как будет выглядеть шаблон заранее. В качестве простого примера, если бы у меня была функция шаблона

template = function (data) {
    return {
        title: data.title
    }
}

тогда я мог бы запустить template({ title: "Steve" }) и вернуть объект

{ title: "Steve" }

, потому что data.title не оценивается, пока я не вызову функцию шаблона. Но я создаю объект на основе пользовательского ввода, где имена полей не известны заранее и могут быть глубоко вложенных в любом месте объекта.

если я определяю объект, который возвращается заранее, тогда data.title поле в Примере уже будет оценено и не будет использовать входные данные. Например, я хочу иметь возможность определить объект шаблона как

obj = { title: this.title }

затем переопределите шаблон как

template = function () {
    return obj
}

и звонок template.call({title:"Steve"}). Но в настоящее время я возвращаюсь

{ title: undefined }

, потому что this.title был уже оценен, когда я определил obj. Может быть, я подхожу к этому неправильно, потому что я все время прихожу к выводу, что мне нужно изменить функцию, построив ее, изменив строку, чтобы включить недооцененный код this.title и создание новой функции из строки. Но это кажется ужасной идеей.

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

EDIT: чтобы было более ясно, что входные данные и структура шаблона не обязательно будут совпадать, я могу захотеть иметь шаблон, который выглядит как

template = function (data) {
    return {
        name: "Alfred",
        stats: {
            age: 32,
            position: {
                level: 10,
                title: data.title
            }
        }
    }
}

и звонок template({title:"Manager"}) и

{ "имя": "Альфред", "статистика": { "возраста": 32, "позиция": { "уровень": 10, "название": "менеджер" } } }

2 ответов


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

  1. мне нужны только допустимые значения JSON, поэтому я могу с уверенностью сказать, что функции не являются буквальным пользовательским вводом
  2. в формате JSON.преобразовать в строки есть параметр replacer которая будет проходить в объект и может использоваться для передачи входных данных в шаблон

С помощью шаблона генератор такой

var templateMaker = function (object) {
    return function (context) {
        var replacer = function (key, val) {
            if (typeof val === 'function') {
                return context[val()]
            }
            return val;
        }
        return JSON.parse(JSON.stringify(obj, replacer))
    }
}

Я создаю объект шаблона, заменяя имена полей функциями, которые возвращают имя поля

var obj = {
    name: "Alfred",
    stats: {
        age: 32,
        position: {
            title: function () { return 'title' },
            level: function () { return 'level' }
        }
    }
}

затем я создаю функцию шаблона, определяю свой ввод и отображаю его в объект

var template = templateMaker(obj);

var data = {
    title: "Manager",
    level: 10
}

var rendered = template(data);

и волшебным образом выход объекта выглядит как

{ "name": "Alfred", "stats": { "age": 32, "position": { "title": "Manager", "level": 10 } } }


может быть, шаблоны двигателей, как ус поможет вам с этим.

вы можете определить шаблон объекта в строке:

var template = '{ title: {{title}} }';

затем визуализируйте его с данными и преобразуйте его в json:

var data = {title: 'I am title'};
var obj = JSON.parse(Mustache.render(template, data));

обновление:

Я прочитал ваш обновленный пример, вот соответствующий пример:

var template = JSON.stringify({
    name: "Alfred",
    stats: {
        age: 32,
        position: {
            level: 10,
            title: '{{title}}'
        }
    }
});

var data = {title: 'I am title'};
var obj = JSON.parse(Mustache.render(template, data));

obj.stats.position.title == "I am title";