Best practice for storing HTML templates on a page?
I'm developing a rather heavy JavaScript interface to a site I'm b开发者_如何转开发uilding, and I've decided to use the (recently made official) jQuery templates plugin to generate my elements from my queries to a JSON API. Now, the problem I'm currently having is:
I'm prone to have a bunch of these templates around. One for each kind of object, some for lists, some for sections of the page, etc. Is there any preferred way of storing these templates? I've read about defining a <script>
tag with an id
using the template name, and then retrieving the text from there (as John Resig describes in "JavaScript Micro-Templating"), but having a bunch of those <script>
tags in every single page looks a bit hackish.
So, the question is: is there any 'best practice' for this kind of scenario?
Why not just load your templates in a hidden element and then use $(template).clone()
? That saves a lot of escaping headaches. I can't speak to performance on .clone()
vs the <script>
approach, but I can tell you that extra script tags are a performance penalty and just generally make code muddy.
Why?
Even though you have a snazzy escaping utility, mistakes will still be made, and they'll be that much harder to read through. Plus if you have to work in a team situation, especially if people roll on/roll off the project, it may not be easily understandable.
you could create a pointer object, say,
templates = {}
, and load it up with jquery object pointers to your clone-able elements like so:templates = {}; templates.message = $("#templates .message"); templates.dialog = $("#templates .dialog");
now all you have to do to create a new template is:
var newDialog = templates.dialog.clone();
You could make a wrapper function to accept params, and then add these with newDialog.find("title").html(title), newDialog.find("message").html(message),
etc.
Again, from a performance perspective, I don't know which is faster, as i don't have time to test right now. But I know that using sanctioned methods is generally better when working on a codebase large enough to require templates... its inevitable that other people will be involved eventually, and the more you have to be around to explain things, the less time you have to do your own badass coding.
Another important aspect of performance is timing... if you are experiencing performance delays, you should make sure to break up your chunks of lengthy executable code by using setTimeout. It creates a new stack and lets the browser paint what it's already processed up to the point just before the new stack is created. This helps immensely when dealing with visual delays as part of a performance issue (typically the most common performance issue noted, especially by non-coders). If you want some more info on that, send me a message and I'll gather up some resources. Limited time right now, putting out fires at work. :)
I have recently done this excercise and although the <script>
tag approach seems a bit hackish, I accepted this as good solution and opted for my own version (John Resigs version is obviosly really good, but I went for my own easily understandable for my own brain version)
My version is a basic template and replacement using replacable values in the form
##VALUE##
TEMPLATE: (single item template or row template)
<script type="text/html" id="ItemTemplate">
<table>
<tr>
<td>##LABEL1##</td>
<td>##VALUE1##</td>
<tr>
</table>
</script>
CONTENT CONSTRUCTION FUNCTION:
function constructFromTemplate(content, values, appendTo) {
var modifiedHtml = content;
modifiedHtml = modifiedHtml.replace(new RegExp('__', 'g'), '##');
$.each(values, function (n, v) {
modifiedHtml = modifiedHtml.replace(new RegExp('##' + n + '##', 'g'), v);
});
if (appendTo != null)
{
$(appendTo).append(modifiedHtml);
//initializePageElements();
}
return modifiedHtml;
}
USAGE
The content will be returned from the function and/or you can set the appendTo parameter set the elementID
to automatically append
the content. (set null
to not append
)
The replacable values are just added as a dynamic object where the object
names are the replaceable items.
var theContent = constructFromTemplate(ItemTemplate, { LABEL1: 'The Label 1 content', LABEL2: 'The Label 2 content' }, null);
note:
I have commented out //initializePageElements();
, this is used to initialize jQuery
plugins, styles on the template.
Only inline styles seem to work when inserting the content into the DOM
look at https://github.com/inspiraller/STQuery
STQuery uses all of the same method names as jquery but instead of manipulating elements on the dom, it works directly on the string:
var strTemplate = '<div id="splog"><h1>lorem ipsum</h1><div class="content">lorem ipsum</div></div>';
var ST = STQuery(strTemplate);
ST.find('h1').html('Hello');
ST.find('.content').html('World!');
var strTemplateUpdated = ST.html();
This keeps logic seperate from the template, ie unobtrusive html templates.
The advantages over jquery is that STQuery doesn't have to write to the DOM first, which means you could use web workers or do all your template manipulation on the server. Note: as of this message, stquery has only been written in javascript so would need to be converted to the server side language of choice.
I've tried many different techniques for this over the past year, and I agree that the script
trick feels a bit wrong but I think it's the best we have.
Any template that needs to be present when the page loads has to be part of the DOM, period. Any attempt at storing them elewhere and loading them creates a noticeable lag.
I've written some template helpers that allow me to insert the necessary templates on the page, while still making it possible to lazy-load them via AJAX when needed. I load all of the templates on the page into a variable on page load, which makes it a little easier to reference.
I would certainly like to hear how others have tackled this issue.
I used script successfully with my framework jquery pure html templates
Regarding of the best practices, please have a look on the new interface of twitter, using one page for everything and only routing internally via "#!/paths".
Using single page website seams to be the next big step for web applications, personally I like to call it web 3.0 :) It will also eliminate problem with having all the same templates on each page - you will have only one page.
In asp.net mvc I often pack my common templates in a partial view which I can include where I need it. That way I do not need to repeat my templates all over the place.
Another approach is to have your templates in a separate files. Like newslist.tmpl.html which allows you to load the template with ajax. Considering this can be done in parallell with the loading of data it shouldn't slow down you application, as it most likely is faster than the data call anyway.
精彩评论