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:
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?
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.
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?
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.
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.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 thedust.register
call executes, which associates thebody0
function with the nameintro
indust.cache
. After that, every time you calldust.render("intro"...)
, dust looks up theintro
template indust.cache
and executes the function associated with it.Store the output of
dust.compile
in a.js
file, such asintro.js
for the example above. You can then includedust-core.js
andintro.js
on the page just like any other JavaScript files (e.g. inscript tags
or via loaders).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 ascript
tag.
You shouldn't have to contain the template in script tags, your second way is better.
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).
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.
I'd say other than missing the build step I mentioned above, you're on the right path.
来源:https://stackoverflow.com/questions/21356235/basic-example-of-client-side-templating-with-dust-js