문제

This is my first foray into client-side templating and I want to make sure I'm understanding it and using it correctly. After reading this LinkedIn engineering blog, I decided to go with dust.js rather than mustache or handlebars. Note that this stackoverflow post answered many of my questions, but I still have a few things I want to clarify.

In the environment I work in I have no access to anything on the server side, so everything I create has to be able to run entirely in the client's browser. For this example, I'll try to recreate this code sample from the LinkedIn Dust Tutorial.

I include dust-full.js rather than dust-core.js because I'm going to compile the template on the fly:

<script src="js/dust-full.js"></script>

Here is the HTML:

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

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

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

And the JavaScript (using 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 seems to work fine, as you can see in this jsfiddle.

A couple questions:

  1. Why should the template be contained within script tags? Why not just include it in a div with id="entry-template" and then replace the html inside that during the dust.render(), like in this modified fiddle?

  2. What does "dust.loadSource(compiled);" do? In the docs it says "If you include the 'compiled' string as part of a script block of JS that you load, then the 'intro' template will be defined and registered. If you want to do it immediately then" call it, however I do not understand what that means. I have noticed that if I remove that line then it doesn't work, however, so I'd like to understand it.

  3. After I'm satisfied with my template and finalize it, how should I compile it so that I import the lighter dust-core.js rather than have it be compiled by the browser on every page load? Is there a significant advantage to doing this or should I leave as is with dust-full.js?

  4. More generally, does this look like an appropriate / useful way to implement dust (or any templating framework for that matter) or am I just way off somewhere?

Thanks in advance.

도움이 되었습니까?

해결책

  1. If you put it in a div, the markup will render as soon as the page loads, and with contain the dust {placeholder} syntax. Then, once the client-side rendering happens, it'll suddenly be replaced with the fully rendered content. In a simple example, this can happen so fast you don't notice it. However, depending on how long it takes to download the templates, the dust JS libraries, fetch the JSON (if it's not already embedded in the page), the JS performance of the browser, and other things happening on the page, this switch may be very noticeable to a user, which is not a good experience.

  2. When you compile a dust template, the output is String that contains a JavaScript function. It will look something like:

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

    When you pass this string to dust.loadSource, all it does is eval it, executing this self-calling function. The result is that the dust.register call executes, which associates the body0 function with the name intro in dust.cache. After that, every time you call dust.render("intro"...), dust looks up the intro template in dust.cache and executes the function associated with it.

  3. Store the output of dust.compile in a .js file, such as intro.js for the example above. You can then include dust-core.js and intro.js on the page just like any other JavaScript files (e.g. in script tags or via loaders).

  4. Usually, you store each dust template in a separate file, such as intro.tl and use some sort of build system (e.g. http://gruntjs.com/) to automatically compile it into a .js file every time it changes. You then concatenate all the generated .js files into a single file (grunt can do this too) and load that on the page in a script tag.

다른 팁

  1. You shouldn't have to contain the template in script tags, your second way is better.

  2. loadSource will run the compiled output of your template, which includes registering it so that other templates and dust.render can reference the compiled output chain through its name ("intro" in this case).

  3. This involves pre compiling your templates before you even open up the browser. So you might have a folder that has all your templates as .tl files. In some build step, you would compile all these templates (using dust.compile) and save the output as .js files. Then the browser would actually load those .js files. This also gets rid of the need for dust.loadSource. The advantage here is not having to include the compiler and the parser, which add up to ~3000 lines of code. The dust library size goes from 4000 lines of code to just 800 lines of code. EDIT: Also, as you mentioned, you're not compiling templates on the fly in the browser, so that will also be a big performance gain.

  4. I'd say other than missing the build step I mentioned above, you're on the right path.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top