问题描述:

Update: after another day of digging

into this issue, I have found that the

current jQuery template lib provides

no way to do this. this article

describes a good approach.

I would still like to hear of any

additional thoughts on doing this. The

article linked above requires that the

returned string of templates be

inserted into the DOM. Seems as though

leaving the DOM out of this would be

ideal, and less overhead on the

browser. Imagine a large page, with

multiple composite templates that may

not get used. Although, maybe because

the templates are wrapped in a script

tag, there is only a single DOM item per template? Come on, let's

hear some thoughts...

Using jQuery template libs, what's the best way to combine multiple, related, relatively small templates together? Do you need a single <script> tag for each individual template? What about in the case of dynamically pulling these templates via AJAX? Can I combine these templates somehow?

Consider the following:

<script id="movieTemplate" type="text/x-jquery-tmpl">

{{tmpl "#titleTemplate"}}

<tr class="detail"><td>Director: ${Director}</td></tr>

</script>

<script id="titleTemplate" type="text/x-jquery-tmpl">

<tr class="title"><td>${Name}</td></tr>

</script>

Now because these two templates are very closely related (and one depends on the other) it would make sense to consolidate these into a single AJAX call, and get them both at once. I have a few ideas, but I'd like to know if there is common/best way to do this? Currently I pull in a chunk of HTML, and then do a .find() to get the specific peice of HTML for a template... e.g.:

var templatePackage = fancyAjaxCalltoGetTemplates();

"templatePackage" might then look like this:

<div id="templatePkg">

<div id="movieTemplate">

{{tmpl "#titleTemplate"}}

<tr class="detail"><td>Director: ${Director}</td></tr>

</div>

<div id="titleTemplate">

<tr class="title"><td>${Name}</td></tr>

</div>

</div>

I could then do:

var titleTemplate = jQuery.template('titleTemplate', $(templatePackage).find('#titleTemplate') );

and

var movieTemplate = jQuery.template('movieTemplate', $(templatePackage).find('#movieTemplate') );

...let me know what you think... what would you do?

网友答案:

I like the referenced article in your update, except the assumption that you can't cache templates unless you insert them into the DOM. From the jQuery.tmpl documentation,

"To cache the template when using markup that is obtained from a string (rather than from inline markup in the page), use $.template( name, markup ) to create a named template for reuse. See jQuery.template()."

Using this, we can build a javascript template management system that allows us to load as many templates at a time as we need while keeping the DOM clean. On the client, keep a hash of template objects by name. You can use your favorite object based javascript pattern here, but I would think the structure could be like this:

templates[templateName] = {
    templateMarkup: markupFromServer,
    loadedAt: Date.now(),
    compiledTemplateFunction: jQuery.template( templateName, markupFromServer )
}

Then use the templates to generate HTML like this:

templates['unique-name'].compiledTemplateFunction(inputData)

Then, build an unload mechanism to free up memory:

function unload(templateName) {
    delete templates[templateName];
    delete jquery.template[templateName];
}

Most importantly, you now have a method of storing multiple templates so you can make requests like: $.get('/TemplateManagement/Render', arrayOfTemplateNamesToLoad, loadManyTemplatesSuccess) to load multiple templates at a time. The only thing we need is a controller TemplateManagement that will take an array of template names as an input and return JSON that pairs a template name with its markup. There are a few ways to do this but it seems to me the most convenient is to define partial views for each template. In ASP.NET MVC 3, you can use this technique and RenderPartial to emit each template's markup into a JSON response. You can either name the partial views the same as the templates or map the names in some custom way.

网友答案:

OK, I read the article you reference in this post. As I see it, his way is probably one of the best ways to load up the template page(s). The only thing I don't like is the asynchronous problems that could crop up, esp. if you need to immediately do some templating before the async get returns... plus any binding issues that could happen before it returns something. In several projects I have done I use his "ancient" SSI (server side includes), but I just use something even easier like:

<% Response.WriteFile("this_page_template_file.html"); %>

You could put it anywhere where you'd place a tag. Like he says, just put in only the templates you need, or maybe include two templates: one is a "base" template with commonly-used items and the second one would have the page-specific ones with template references {{tmpl}}.

Is this even close to an answer? ;-)

网友答案:

[First off, great question. I love this topic]

I have no experience with the plugin "jquery-template-libs", but there is a particular lightweight javascript template plugins that are becoming almost a standard and plays very nicely with jQuery, which is probably better suited for the task than JTL, Mustache:

https://github.com/janl/mustache.js

It's got something that's called a "partial" which is essentially a way to include smaller templates within another one. Which sounds like it will help you out a lot.

On top of that there is a library called ICanHaz.js:

http://icanhazjs.com/

ICanHaz essentially extends Mustache to include built in functionality for templates and works incredibly well.

Mustache/ICanHaz allow you to add templates by variable, by a json call or by using tags. The choice is yours.

网友答案:

I know this is an old question but you might want to take a look at Closure-Templates. They provide the kind of functionality you're after with the added advantage of being compiled into JavaScript at compile-time instead of at run-time in each user's browser.

If you do decide to look into using them then I'd suggest using plovr for building them.

相关阅读:
Top