自定义模板

时间:2015-08-17 05:52:13

标签: javascript json regex string templates

我想了解如何实现以下任务的一些想法。 我正在编写一个轻量级的模板语言。它接受任何数组或json对象,并用我本地数据存储中的值替换字符串值。 请让我说明它是如何工作的:

var obj = {
  prop: "_p{propnameA}",
  secondprop: "_p{propnameB}",
  thirdprop: "Hello, this is \"_p{propnameC}\" and _p{propnameD},
  arr: [
    "textvalue", "propB value = _p{propB}"
  ]
}

我写了一个迭代每个json或数组的每个属性的算法。现在我需要一种快速的方法来将我的所有模板标签替换为它们的实际值。 我想使用不同类型的模板标签:

  • _p {...}
  • _c {...}
  • _v {...}

每个模板标签在我的程序中意味着不同的东西。例如:template-tag _p {}使用tag-value的参数调用应用程序中的方法。 _p {propval} 相当于 myApp.getProperty(" propval")

其他标签调用我的应用程序的其他方法。 我正在考虑使用带有正则表达式的string.replace作为我的标签。但我遇到两个问题:

  1. 如何写这个正则表达式?
  2. 如何处理非字符串返回值?
  3. 标记的评估值不能总是字符串。它也可以是更复杂的数据类型,如数组或json对象。在我在这个问题顶部的第一个示例代码中," _p {propnameA}"的结果值可能是像[1,2,3,4]这样的数组。或者_p {propnameB}可以是一个数字,因此我在顶部的示例应评估如下:

    obj = {
      prop: [1, 2, 3, 4],
      secondprop: 827,
      thirdprop: "Hello, this is \"valueC\" and valueD",
      arr: ["textvalue", "propE value = 827"]
    }
    

    显然obj.secondprop不应该有字符串值" 827"但是数字而不是obj.arr [1]应该是一个字符串。

    你有一些聪明的想法怎么做? 非常感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

如果我理解正确,你正在寻找这样的东西:



// evaluate a single placeholder like _p{foo}

function evalPlaceholder(prefix, content) {

  switch(prefix) {
      case "_p": do_this();
      case "_c": do_that();      
      //etc
  }

}

// eval a string with placeholders

function evalTemplate(str) {

  var m = str.match(/^(_\w){([^{}]+)}$/);
  if(m) {
    // the whole string _is_ a placeholder
    return evalPlaceholder(m[1], m[2]);
  }
    
  // otherwise, the string can _contain_ placeholders
  return str.replace(/(_\w){(.+?)}/g, function(_, $1, $2) {
    return evalPlaceholder($1, $2);
  });

}

// walk an object recursively and eval all templates

function evalObject(obj) {
  
  Object.keys(obj).forEach(function(k) {
    var v = obj[k];
    
    if(typeof v == "object")
      evalObject(v)
    else
      obj[k] = evalTemplate(v);
    
  })

}




答案 1 :(得分:0)

首先,您可以通过两种方式将数值转换为字符串,我相信您之前已经看过类似的内容:

1- toString函数调用:var x = 825; console.log(x.toString())

2-将数字添加到字符串中:var x = '' + 825

因此,如果您不想要数字值,而只需要字符串,请确保在使用之前将值转换为字符串(即使它不会发生任何字符串)。

第二,我不认为我真的遇到了你的问题,但是从我得到的,你的问题比正则表达式更简单,你只是替换定义良好的字符串,所以在迭代值时你所需要的只是:

var p = prop.toString();
if(p.startsWith("_p") {
  p.replace("_p", "_c)
}

我希望这就是你要找的东西