3

我有一个 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 并将其吐回

我究竟做错了什么?

4

3 回答 3

2

我究竟做错了什么?

使用真实的<img>.

当您使用类似<img src>的属性时,浏览器可能会修复您的值以使其有效。因此,由于这些字符{}在 URL 中无效,浏览器可能会将它们编码为%7B%7D. 这可能是特定于浏览器的;尼克的例子,他说我在 Firefox 中失败了。(由于缺少varon test_template,它在 IE 中也失败了,但这是一个不相关的问题。)

请记住,当您编写 HTML 元素时,不会维护 HTML 源代码。浏览器会将其解析为大量 DOM 节点。当您调用html()( innerHTML) 时,您得到的是这些 DOM 节点的序列化,它不会完全保留原始标记的格式。特别是当原始标记不是真正有效的 HTML 而只是模板的占位符时。

出于这个原因,我不会使用实际的页内元素作为模板,并且我认为 jquery-tmpl 用它的$(element).template()方法鼓励这样做是一个错误。这不是我使用插件的唯一问题。例如,如果您data()在模板内的元素上放置或事件处理程序,则由于天真innerHTML的复制和 jQuery 可怕的节点身份黑客攻击,该数据/处理程序会被意外复制到 IE 而不是其他浏览器上。

因此,如果您必须使用jquery-tmpl,请使用字符串,而不是节点。如果必须,请使用嵌入在 a 中的字符串<script>,但不要使用实际的页内元素。(除了这个问题,在文档中包含不是实际内容的内容在语义上也是有问题的。)

于 2010-10-17T22:54:33.983 回答
1

确保您使用的是最新版本的模板插件,我使用最新的插件和 jQuery 1.4.2 或 1.4.3 都没有问题。

您可以在此处查看您的代码的工作演示

于 2010-10-17T22:30:46.813 回答
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
        }

只需在渲染模板上调用该函数

于 2011-08-13T13:44:07.843 回答