使用Dust.js的客户端模板化的基本示例

19

这是我第一次尝试客户端模板,我希望确保我理解并正确使用它。在阅读了LinkedIn工程博客之后,我决定选择dust.js而不是mustachehandlebars。请注意这篇stackoverflow文章回答了我的许多问题,但我仍然有一些需要澄清的事情。

在我工作的环境中,我无法访问服务器端的任何内容,因此我创建的所有内容都必须能够完全在客户端浏览器中运行。在这个例子中,我将尝试重新创建this code sample,它来自于LinkedIn Dust Tutorial
我包含了dust-full.js而不是dust-core.js,因为我要动态编译模板:
<script src="js/dust-full.js"></script>

这是HTML代码:

<script id="entry-template">
{title}

<ul>
    {#names}
    <li>{name}</li>{~n}
    {/names}
</ul>
</script>

<div id="output"></div>

而 JavaScript(使用 jQuery):

$(document).ready(function () {
    var data = {
        "title": "Famous People", 
        "names" : [{ "name": "Larry" },{ "name": "Curly" },{ "name": "Moe" }]
    }

    var source   = $("#entry-template").html();
    var compiled = dust.compile(source, "intro");
    dust.loadSource(compiled);

    dust.render("intro", data, function(err, out) {
        $("#output").html(out);
    });
});

这似乎可以正常工作,你可以在这个jsfiddle中看到。
有几个问题:
  1. 为什么模板应该被包含在script标记中? 为什么不只是将其包含在id =“entry-template”的div中,然后在dust.render()期间替换其中的html,例如this modified fiddle中所示?

  2. "dust.loadSource(compiled);"是什么意思? 在the docs中说:“如果您将'compiled'字符串作为要加载的JS脚本块的一部分包含在其中,那么'intro'模板将被定义并注册。 如果你想立即做到这一点,就调用它”,但我不明白这是什么意思。 我已经注意到,如果我删除该行,则不起作用,因此我想了解它。

  3. 当我满意我的模板并完成它后,应该如何编译它,以便导入较轻的dust-core.js,而不是让浏览器在每个页面加载时进行编译? 这样做有显着优势吗,还是应该像使用dust-full.js那样保持不变?

  4. 更普遍地说,这看起来像实现dust(或任何模板框架)的适当/有用的方式吗,还是我完全走错了?

提前感谢。

2个回答

11
  1. 如果将内容放在一个div中,它会在页面加载时立即呈现,并包含{placeholder}语法的占位符。然后,一旦客户端进行渲染,它将被完全渲染的内容替换。在简单的情况下,这个过程可以非常快,你可能不会注意到它。但是,取决于下载模板、Dust JS库、获取JSON(如果它没有已经嵌入到页面中)、浏览器的JS性能以及页面上发生的其他事情需要多长时间,用户可能会非常注意到这个切换,这并不是一个好的体验。

  2. 当您编译Dust模板时,输出是包含JavaScript函数的字符串。它看起来像这样:

    (function() { dust.register("intro", body0); function body0(chk, ctx) { /* [...] */ } })();

    当您将此字符串传递给dust.loadSource时,它只会将其eval,执行此自调用函数。结果是dust.register调用执行,它将body0函数与dust.cache中的名称intro关联起来。之后,每次您调用dust.render("intro"...),dust都会查找dust.cache中的intro模板并执行与之相关联的函数。

  3. dust.compile的输出存储在一个.js文件中,例如上面的例子中的intro.js。然后,您可以像其他JavaScript文件一样在页面上包含dust-core.jsintro.js(例如在script tags或通过加载器)。

通常情况下,您会将每个Dust模板存储在单独的文件中,例如intro.tl,并使用某种构建系统(例如http://gruntjs.com/)自动编译它成一个.js 文件。每次更改时,您都会重新生成所有的.js文件,并将其连接成单个文件(grunt也可以完成此操作),然后在script标签中加载该文件。

谢谢Yevgeniy!那么关于问题#1,这是否意味着使用dust设置的动态页面通常几乎没有实际的HTML?基本上只需导入已编译的模板,使用任何数据进行渲染,然后将其插入到空div中?感谢grunt链接! - dougmacklin
@DougieBear 是的,使用客户端渲染的网页相对来说标记很少。通常只有足够的标记布置页面的基本结构,然后是脚本标签和嵌入式JSON以填充所有内容。 - Yevgeniy Brikman

1
  1. 你不需要把模板包含在script标签中,第二种方式更好。

  2. loadSource将运行你的模板的编译输出,其中包括注册它,以便其他模板和dust.render可以通过其名称(在本例中为“intro”)引用编译输出链。

  3. 这涉及在甚至打开浏览器之前预编译您的模板。因此,您可能有一个文件夹,其中包含所有模板作为.tl文件。在某个构建步骤中,您将编译所有这些模板(使用dust.compile)并将输出保存为.js文件。然后浏览器实际上会加载这些.js文件。这也消除了对dust.loadSource的需求。优点在于不需要包含编译器和解析器,这两者加起来约为3000行代码。 dust库大小从4000行代码减少到仅800行代码。编辑:另外,正如您提到的,您不会在浏览器中即时编译模板,因此这也将是一个很大的性能提升。

  4. 除了缺少我上面提到的构建步骤之外,我认为你走在正确的道路上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接