underscore.js nested templates

Is it possible to somehow take a DOM element from a underscore template and use it as another template?

The idea is that my app needs to render a document that contains a loop with items and a summary. I need to occasionaly re-render only the summary or a few items, so I cannot just re-render the whole document.

However, I would like to keep it simple for the app users to create their own templates for the document and I think that keeping everything in one file for a document would make it easier.

I'm trying to use something like this:

<script type="text/template" id="document-template">
    <div id="document">
        <h1><%= name %></h1>
        <ul class="items">
            <% _.each(items, function(item) { %> 
                <li><%= item %></li>
            <% }); %>
        </ul>
        <div id="summary">
            <p>Total items: <%= totalitems %></p>
        </div>
    </div>
</script>

Now, I can easily do this var documentTemplate = _.template($('#document-template').html()); to turn this into a document template, but I would like to turn the summary part into a template and a list item into a template as well.

Can I do something like this:

var summaryTemplate = _.template($('#document-template #summary').html());
var itemTemplate = _.template($('#document-template .items li').html());

PS. Actually I am loading the template from an external file using jQuery's $.get. This way I will get the document-template in one big string. From there, I can do just documentTemplate = _.template(loadedString); .

Now, if I could just extract the #summary element from the string, it should work. But when I try to convert the string to DOM element ( var domElement = $(loadedString) ) (so I could do this: summaryTemplate = _.template($('#summary',domElement).html()); , it won't work, because underscore won't recognize the <%= %> tags anymore.


You can pass the nested template as a variable in the template assignments to the main template, eg:

HTML:

<script type="text/template" id="sub_template">
  <article>
    <h1>id: <%= id %><h1>
  </article>
</script>

<script type="text/template" id="main_template">
  <% for (var i = 0; i < num; i++) { %>
    <%= renderSub({id:i}) %>
  <% } %>
</script>

JS:

 var renderSub = _.template( $('#sub_template').remove().text() ),
     renderMain = _.template( $('#main_template').remove().text() );

  renderMain({num:5, renderSub:renderSub});

操场

/////// TEMPLATES //////

    var mainTemplate = "<ul> 
                          <% _.each(items, function(item) { %> 
                               <%= listItem({item:item}) %> 
                          <% }); %> 
                        <ul>";

    var subTemplate = '<li><%=item %></li>';


/////// MODEL (our data) //////

    var model = {
        items : [1,2,3,4,5]
    }


/////// COMPILE //////

    // add the subTemplate to the model data, to be passed to the mainTemplate
    model.listItem = _.template(subTemplate);

    // Render main template to the DOM
    document.body.innerHTML = _.template(mainTemplate, model);

Instead of loading it all at once as one template and then trying to load a portion of it again later, separate them as multiple templates.

Have your main document-template and a summary-template. The initial load pulls in the document-template and then pulls into the summary-template and inserts it into the compiled DOM from the first template. Then you can reload the second template at any time. See the following steps:

1) Load initial template, shown below:

<script type="text/template" id="document-template">
    <div id="document">
        <h1><%= name %></h1>
        <ul class="items">
            <% _.each(items, function(item) { %> 
                <li><%= item %></li>
            <% }); %>
        </ul>
    </div>
</script>

2) Once this is compiled into the DOM, load the second template via underscore, shown below:

<script type="text/template" id="summary-template">
    <div id="summary">
        <p>Total items: <%= totalitems %></p>
    </div>
</script>

3) Call $("#document").append(summaryTemplate), or whatever variable is holding the compiled template.

4) Repeat steps 2 and 3 any time you need to reload the summary, except first remove the existing $("#summary") before appending again

You can use this same strategy for the items as well, just make sure you use the correct jQuery selectors/methods so that you're overwriting the existing divs in the correct order, as append will only work for adding something to the end of an element.

链接地址: http://www.djcxy.com/p/72070.html

上一篇: 我如何/然后在“小胡子”

下一篇: underscore.js嵌套模板