我有一个jquery模板:
<div id="test_template">
<img src="${url}" width="31" height="32" alt="" />
${url}
</div>
我用这个编译它:
test_template = $('#test_template').template();
我用这个渲染它:
$.tmpl(test_template, {url:'http://sstatic.net/stackoverflow/img/sprites.png'}).appendTo('#render_test');
最终结果如下:
<div id="render_test">
<img height="32" width="31" alt="" src="$%7Burl%7D"> http://sstatic.net/stackoverflow/img/sprites.png</div>
显然我希望URL在src =“”标签中......但它不是(尽管它在标签之后正确输出)。如果我查看template()创建的匿名函数,我发现它没有将src =“$ {url}”转换为javascript。它只是将其编码为HTML并将其吐出来
我做错了什么?
答案 0 :(得分:2)
我做错了什么?
使用真实的<img>
。
当您使用<img src>
等属性时,浏览器可能会修复您的值以使其有效。因为字符{}
在网址中无效,浏览器可能会将其编码为%7B%7D
。这可能是特定于浏览器的;尼克的例子,他说在Firefox中我的工作失败了。 (由于var
上缺少test_template
,它在IE中也失败了,但这是一个无关的问题。)
请记住,在编写HTML元素时,不会维护HTML源代码。浏览器会将其解析为一堆DOM节点。当您调用html()
(innerHTML
)时,您获得的是这些DOM节点的序列化,这并不完全保留原始标记的格式。特别是当原始标记不是真正有效的HTML而只是一个用于模板化的占位符时。
由于这个原因,我不会使用实际的页内元素来模板化,并且我认为jquery-tmpl使用$(element).template()
方法鼓励这样做是错误的。这不是我使用插件的唯一问题。例如,如果您在模板内的元素上放置data()
或事件处理程序,那么由于天真innerHTML
复制和jQuery的可怕节点身份,该数据/处理程序会被意外地复制到IE而不是其他浏览器上破解。
因此,如果您必须使用jquery-tmpl
,请使用字符串,而不是节点。如果必须,请使用<script>
中嵌入的字符串,但不要使用实际的页内元素。 (除了这个问题,在文档中包含非实际内容的内容也在语义上有问题。)
答案 1 :(得分:1)
确保您使用的是最新版本的模板插件,使用最新的插件以及jQuery 1.4.2或1.4.3时没有任何问题。
答案 2 :(得分:0)
我用一个使用TmplItem的丑陋黑客解决了这个问题:
function fixRenderedTemplate(rendered){
var fixArray = [["img", "src"], ["a", "href"]];
for (var i=0; i<fixArray.length; i++){
var tagName = fixArray[i][0];
var attrName = fixArray[i][1];
$(tagName, rendered).each(function(index, elem){
var data = $(elem).tmplItem().data;
var fixTemplate = unescape($(elem).attr(attrName));
var url = $.tmpl(fixTemplate, data).text();
$(elem).attr(attrName, url);
});
}
return rendered
}
只需在渲染模板上调用该函数