在 underscore.js 模板引擎中运行模板中的模板(递归)

发布于 2024-12-14 09:37:57 字数 515 浏览 2 评论 0原文

我正在使用backbone.js 和underscore.js 构建一个javascript 应用程序。经过几个小时的阅读并尝试在如下所示的模板中运行模板后,它变得越来越令人沮丧。

我的模板使用 underscore.js 模板引擎中的构建:

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

我想为每个子元素渲染此模板( render_this_template_recursively(child) )。

我该怎么做?

谢谢

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 more and more frustrating.

My template using the build in underscore.js template engine:

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

I would like to render this template for every child element ( render_this_template_recursively(child) ).

How can I do this?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

扶醉桌前 2024-12-21 09:37:57

我没有亲自尝试过这个,但 _.template 返回一个函数(我将其命名为 templateFn 来强调这一点),因此您可以将其传递到模板中,如下所示:

var templateFn = _.template($('#navigation_template').html());

$(this.el).html(templateFn({model: this.model, templateFn: templateFn}));

请注意,我正在传递整个模型(假设你的模型有一个children属性,它本身就是骨干模型的集合),你的模板将更改为:

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

祝你好运。我希望这对你有用

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

分开我的手 2024-12-21 09:37:57

我刚刚成功尝试了这个。我只用纯 UnderscoreJS 测试了它,没有使用 BackboneJS,但从功能上来说这应该不重要。

这是代码:

<!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>

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>
云巢 2024-12-21 09:37:57

我尝试使用 timDunham 和 Ates Goral 提供的示例,但它对我不起作用,所以我对其进行了一些升级。在下面找到它。

视图:

    template: _.template($("#tree").html()),

    render: function () {
        this.$el.html(this.template({
            options: this.collection.toJSON(),
            templateFn: this.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>

它对我来说效果很好。正如您所看到的,主要区别是将配置对象传递到 templateFn 中,而不是参数。希望您会发现它很有用。

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.

歌枕肩 2024-12-21 09:37:57

递归模板可以如下所示:

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

首先,预编译模板:

entriesTmpl = _.template(entriesTmpl);

然后在传递数据和模板本身时调用它:

$el.html(entriesTmpl({
    entries: entryTree,
    tmpl: entriesTmpl
});

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
});
过期以后 2024-12-21 09:37:57

我最近使用骨干关系实现了这一点。我创建了一个小提琴,如果您想查看可行的解决方案,我认为它可能会有所帮助: http://jsfiddle.net /blaisco/ADKrK/

我已在下面发布了相关内容。

视图:

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;
    }
});

html/模板:

<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>

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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文