使用 JsRender 从简单数组数据创建 row/column 布局

Use JsRender to create a row/column layout from simple array data

我正在使用 jsrender 编写基于 bootstrap 的 HTML 模板并使用 javascript 呈现 HTML 内容。我的数据如下

var data = [
    {
        'img': 'img/books/kiterunner.jpg',
        'title': 'The Kite Runner',
        'authors': 'Khaled Hosseini'
    },
    {
        'img': 'img/books/tokillamockingbird.jpg',
        'title': 'To Kill A Mocking Bird',
        'authors': 'Harper Lee'
    },
    {
        'img': 'img/books/hungergames.jpg',
        'title': 'The Hunger Games',
        'authors': 'Suzanne Collins'
    }
    .....
]

而我要生成的对应HTML如下

<div class="row-fluid" id="result">
    <script id="template" type="text/x-js-render">
        <div class="col-md-3 col-sm-6">
            <div class="image-tile outer-title text-center">
                <img alt="{{:title}}" src="{{:img}}" style="max-height:350px;">
                <div class="title mb16">
                    <h5 class="uppercase mb0">{{:title}}</h5>
                        <span>{{:authors}}</span>
                </div>
            </div>
       </div>
   </script>
</div>

目前 data 中的每个对象都是单独显示的,但有时,图像的尺寸较大并且会扰乱行的外观。所以我想在 data 中的每个 4 个对象之后用内容重复 div.row-fluid 创建。我目前执行以下操作来注册模板并将数据呈现为所需的 HTML。我似乎无法弄清楚如何在不更改 data.

中的值的情况下使用 {{for}}
var template = $.templates("#template");
var htmlOutput = template.render(data);
$("#result").html(htmlOutput);

谢谢。

编辑:我通过显式 HTML 字符串连接然后在 if 语句中使用 index%4 来决定 div.row-fluid 需要创建。但是,我真的想要一个更优雅的解决方案。添加 jquery 标签以获得更广泛的可见性。

您可以使用自定义 {{range}} 标签 - 请参阅 this sample

这是一个示例,它呈现为 table,其中 <td> 按四组分组 - 对于四列布局:

<script id="myTmpl" type="text/x-jsrender">
  <table>
    {{for rows ~last=rows.length-1}}
      {{if #index%4===0 ~ind=#index}}
        <tr>
        {{range ~root.rows start=~ind end=~ind+3 max=~last}}
          <td>{{:title}}</td>
        {{/range}}
        </tr>
      {{/if}}
    {{/for}}
  </table>
</script>

使用此版本的自定义 {{range}} 标签:

$.views.tags("range", function(array) {
  var ret = "",
    start = this.tagCtx.props.start,
    end = this.tagCtx.props.end,
    max = this.tagCtx.props.max;

  end = end > max ? max : end;

  for (var i = start; i <= end; i++) {
    // Render tag content, for this data item
    ret += this.tagCtx.render(array[i]);
  }
  return ret;
});

var data = {rows: [
    {
        'title': ...
    },
    ...
  ]};

  ...