从模板创建Javascript对象

时间:2014-04-21 09:15:09

标签: javascript json function templates object

我想从模板创建一个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对象模板库,但没找到任何东西。

编辑:为了更清楚地表明输入数据和模板结构不一定匹配,我可能想要一个看起来像

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

并致电template({title:"Manager"})以获取

{     "姓名":" Alfred",     " stats":{         "年龄":32,         "职位":{             "等级":10,             " title":"经理"         }     } }

2 个答案:

答案 0 :(得分:8)

所以我设法通过(ab)使用函数作为元数据来解决这个问题,以标记应该在模板中替换的值。这可以通过两件事来实现:

  1. 我只需要有效的JSON值,所以我可以肯定地说功能不是文字用户输入
  2. JSON.stringify有一个replacer parameter,它将遍历该对象并可用于将输入数据传递给模板
  3. 使用像这样的模板生成器

    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 } } }

答案 1 :(得分:4)

也许像Mustache这样的模板引擎可以帮助你解决这个问题。

您可以在字符串中定义对象模板:

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";