0

几天前我写了一个简单的模板函数,现在的问题是空格会杀死标签。因此,当我输入这样的内容时:<div id="str">#{my} #{name} #{is} #{#{a}}</div>效果很好,但是以下内容却不行:<div id="str">#{my} #{name} #{is} #{ #{a} }</div>.

这是我到目前为止所做的:

$.tmpl = function(str, obj) {
    do {
        var beforeReplace = str;
        for(var key in obj) {
            str = str.replace("#{" + key + "}", obj[key]);
        }
        var afterReplace = str !== beforeReplace;
    } while (afterReplace);

    return str;
};


var map = {
    my: "Am",
    name: "I",
    is: "<a href='#'>awesome</a>",
    a: "#{b}",
    b: "c",
    c: "?"
};

$("#str").html(function(index, oldhtml) {
    $(this).html( $.tmpl(oldhtml, map) );
});

#{a}如果我使用and ,我怎样才能让它工作#{ #{a} }。我知道,这是可能的,甚至很简单,但是我不是正则表达式专家。

行得通

失败了

4

2 回答 2

4

您需要从要替换的键中修剪空格。为此,您可以使用函数作为 String.replace() 函数的第二个参数。您还可以使用这样的函数一次替换每次传递的所有匹配项。因此,请尝试以下操作:

$.tmpl = function(str, obj) {
    do {
        var beforeReplace = str;
        str = str.replace(/#{([^}]+)}/g, function(wholeMatch, key) {
            var substitution = obj[$.trim(key)];
            return (substitution === undefined ? wholeMatch : substitution);
        });
        var afterReplace = str !== beforeReplace;
    } while (afterReplace);

    return str;
};

正则表达式 /#{([^}]+)}/g 查找以“#{”开头的任何字符串的所有出现(“g”表示“全局”),然后至少有一个字符不是“}”,然后以“}”结尾。括号只是用于将键本身分组,以便正则表达式引擎将它作为函数的参数为​​我们提取出来。

另一个正则表达式替换 (/^\s+|\s+$/g) 只是修剪字符串。它找到所有前导和尾随空格并将其删除。在 ECMAScript 5 中,有一个 String.trim() 函数提供了内置的这个功能,但它还不够广泛,无法可靠地使用它。有关详细信息,请参阅MDN 文档

但是,我不确定像这样进行多次传球是否明智。您介绍了无限循环的可能性:

var map = {
    a: "#{b}",
    b: "#{a}"
};

$.tmpl("#{a}", map);

您还介绍了地图中的值可能意外包含 #{...} 并在您无意中扩展的可能性。如果这些值是由用户输入的,这尤其令人担忧。在这种情况下,您刚刚让他可以让您的应用程序无限循环或公开其他键的值。大多数模板引擎不提供以这种方式重复替换参数的能力。

于 2013-02-14T17:09:05.803 回答
1

(function($) {
  $.fn.tmpl = function(obj) {
    var _this = this,
      el = $(this);

    return (function() {
      var original = el.html();

      el.html(el.html().replace(/{{([^}}]+)}}/g, function(wholeMatch, key) {
        var substitution = obj[$.trim(key)];

        return typeof substitution == 'undefined' ? wholeMatch : substitution;
      }));

      return el.html() == original ? _this : $(el).tmpl(obj);
    })();
  };
})(jQuery);

$($('#template').html())
  .tmpl({
    greeting: 'Hello',
    wish: 'everyone a wonderful day'
  })
  .appendTo($('#results'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="results"></div>

<template id="template">
  <p>{{greeting}}, I just wanted to wish <b>{{wish}}</b>!</p>
</template>

于 2016-04-28T09:39:13.080 回答