【问题标题】:Basic Example of Client Side Templating with Dust.js使用 Dust.js 进行客户端模板化的基本示例
【发布时间】:2014-02-16 20:06:46
【问题描述】:

这是我第一次涉足客户端模板,我想确保我理解并正确使用它。阅读this LinkedIn engineering blog 后,我决定选择dust.js 而不是mustachehandlebars。请注意,this stackoverflow post 回答了我的许多问题,但我仍有一些事情要澄清。

在我工作的环境中,我无法访问服务器端的任何内容,因此我创建的所有内容都必须能够完全在客户端的浏览器中运行。对于此示例,我将尝试从 LinkedIn Dust Tutorial 重新创建 this code sample

我包含 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);
    });
});

这似乎工作正常,您可以在 this jsfiddle 中看到。

几个问题:

  1. 为什么模板应该包含在脚本标签中?为什么不直接将其包含在 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. 更一般地说,这看起来是一种合适/有用的方式来实现灰尘(或任何与此相关的模板框架)还是我只是在某个地方?

提前致谢。

【问题讨论】:

    标签: linkedin dust.js client-side-templating


    【解决方案1】:
    1. 如果将其放在div 中,则标记将在页面加载后立即呈现,并且包含灰尘{placeholder} 语法。然后,一旦客户端渲染发生,它会突然被完全渲染的内容所取代。在一个简单的示例中,这可能发生得如此之快,以至于您不会注意到它。但是,根据下载模板、灰尘 JS 库、获取 JSON(如果它尚未嵌入页面中)、浏览器的 JS 性能以及页面上发生的其他事情需要多长时间,此开关可能对用户来说非常引人注目,这不是一个好的体验。

    2. 当你编译一个灰尘模板时,输出是包含一个 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 中或通过加载器)。

    4. 通常,您将每个灰尘模板存储在单独的文件中,例如intro.tl,并使用某种构建系统(例如http://gruntjs.com/)在每次更改时自动将其编译成.js .然后将所有生成的 .js 文件连接到一个文件中(grunt 也可以这样做)并将其加载到页面上的 script 标记中。

    【讨论】:

    • 谢谢叶夫根尼!那么关于问题 #1,这是否意味着设置有灰尘的动态页面通常几乎没有实际的 HTML?几乎只是导入已编译的模板,用任何数据渲染它,然后将其插入到一个空的 div 中?感谢咕噜链接!
    • @DougieBear 是的,使用客户端渲染的网页的标记相对较少。通常只需要足够的标记来布置页面的基本结构,然后使用脚本标签和嵌入​​的 JSON 来填充所有部分。
    【解决方案2】:
    1. 你不应该在脚本标签中包含模板,你的第二种方式更好。

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

    3. 这包括在您打开浏览器之前预编译您的模板。因此,您可能有一个文件夹,其中包含所有模板为 .tl 文件。在某些构建步骤中,您将编译所有这些模板(使用dust.compile)并将输出保存为.js 文件。然后浏览器实际上会加载那些 .js 文件。这也消除了对dust.loadSource 的需要。这里的优点是不必包含编译器和解析器,它们加起来大约 3000 行代码。灰尘库的大小从 4000 行代码到只有 800 行代码。编辑:另外,正如你所提到的,你不是在浏览器中动态编译模板,所以这也将是一个很大的性能提升。

    4. 我想说,除了错过我上面提到的构建步骤之外,您走在正确的道路上。

    【讨论】:

      猜你喜欢
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多