Run Template in Template (recursion) within underscore.js template engine

前端 未结 5 480
深忆病人
深忆病人 2020-12-30 02:59

I am using backbone.js and underscore.js to build an javascript application. Since hours of reading and trying to run a template within a template like below, it is getting

相关标签:
5条回答
  • 2020-12-30 03:41

    I've not personally tried this but _.template returns a function (I've named it templateFn to emphasize that), so you could pass it into the template like this:

    var templateFn = _.template($('#navigation_template').html());
    
    $(this.el).html(templateFn({model: this.model, templateFn: templateFn}));
    

    Notice that i'm passing in the whole model (assuming that your model has a children property which is itself a collection of backbone models) and your template would be changed to:

    <script id="navigation_template" type="text/template">
      <div><%= model.escape('title') %>
          <% _.each(model.children, function(child) { %>
              <%= templateFn(child, templateFn) %>
          <% }); %>
      </div>
    </script>
    

    Good luck. I hope this works for you

    0 讨论(0)
  • 2020-12-30 03:50

    A recursive template can look something like this:

    <ul>
        <% entries.forEach(function (entry) { %>
        <li>
            <%= entry.title %>
            <%
            if (entry.children) {
                print(tmpl({
                    entries: entry.children,
                    tmpl: tmpl
                }));
            }
            %>
        </li>
        <% }); %>
    </ul>
    

    First, pre-compile your template:

    entriesTmpl = _.template(entriesTmpl);
    

    Then call it while passing both your data and the template itself:

    $el.html(entriesTmpl({
        entries: entryTree,
        tmpl: entriesTmpl
    });
    
    0 讨论(0)
  • 2020-12-30 03:50

    I implemented this recently using backbone-relational. I created a fiddle that I thought might be helpful if you want to see a working solution: http://jsfiddle.net/blaisco/ADKrK/

    I've posted the relevant bits below.

    The view:

    var FolderView = Backbone.View.extend({
        el: $("#main"),
    
        template: _.template($("#folder-tmpl").html()),
    
        render: function () {
            this.$el.html(this.template({
                "folder": parentFolder.toJSON(),
                "templateFn": this.template
            }));
            return this;
        }
    });
    

    The html/template:

    <ul id="main"></ul>
    
    <script type="text/template" id="folder-tmpl">
        <li>
            <a href="#" class="folder"><%= folder.title %></a>
            <% if(folder.children.length) { %><ul><% } %>
            <% _.each(folder.children, function(child) { %>
                <%= templateFn({"folder": child, "templateFn": templateFn}) %>
            <% }); %>
            <% if(folder.children.length) { %></ul><% } %>
        </li>
    </script>
    
    0 讨论(0)
  • 2020-12-30 03:57

    I've tried to use example presented by timDunham and Ates Goral, but it did not work for me, so I've made a little upgrade for it. Find it below.

    view:

        template: _.template($("#tree").html()),
    
        render: function () {
            this.$el.html(this.template({
                options: this.collection.toJSON(),
                templateFn: this.template
            }));
        }
    

    and template:

    <script type="text/template" id="tree">
    <ul>
        <% _.each(options, function (node) { %>
            <li><%= node.title %></li>
            <% if (node.children) { %>
                <%= templateFn({ options: node.children, templateFn: templateFn }) %>
            <% } %>
        <% }); %>
    </ul>
    

    And it works pretty good for me. The main difference, as you can see, is the passing configuration object into templateFn, instead of arguments. Hope you'll find it useful.

    0 讨论(0)
  • 2020-12-30 03:58

    I just successfully tried this. I tested it with only pure UnderscoreJS, no BackboneJS but functionally it shouldn't matter.

    Here is the code:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script type="text/javascript" src="underscore.js"></script>    
    <style>
    
    .container {
      position: relative;
      margin-bottom: 20px;
    }
    
    #container {
      position: relative;
      margin: auto;
    }
    
    .fib-box {
      position: absolute;
      top: 0px;
      left: 0px;
      background: rgba(0,68,242,0.15);
      border: 1px solid rgba(0,0,0,0.20); 
    }
    
    .header {
      padding-bottom: 10px;
    }
    
    </style>
      </head>
      <body> 
    
        <div class="header">
            <h3>Render Fibonacci With UnderscoreJS</h3>
            <form id="updateCount">
                <input type="text" value="13" id="fibSequence" />
                <input type="submit" value="Update" />
            </form>
        </div>
    
        <div class="container">
        <div id="container">
    
        </div>    
        </div>
    
    <script type="text/template" id="template">
    <% if(depth){ %>
    <div class='fib-box' data-depth='<%= depth %>' style='width: <%= val %>px; height: <%= val %>px;'></div>
    <% print(template(getFibObj(depth-1))) %>
    <% } %>
    </script>
    
    <script type="text/javascript">
    
    var template;
    
    $(document).ready(function(){
    
        template = _.template($("#template").text());
    
        $("#updateCount").submit( function(){
    
            $("#container").html( template( getFibObj($("#fibSequence").val()) ) );
    
            var width = $("#container .fib-box:first").css("width");
            $("#container").css( {width: width, 'min-height': width} );
    
            return false;
        });
    
        $("#updateCount").submit();
    });
    
    function getFibObj(i){
        return {depth: i, val: fib(i)};
    }
    
    function fib(i){
        return ( i == 0 || i == 1 ) ? i : fib(i-1) + fib(i-2);
    }
    
     </script>
    
      </body>
    </html>
    
    0 讨论(0)
提交回复
热议问题