如何在Mustache.js或Handlebars.js中使用嵌套迭代器?

时间:2021-10-24 14:32:21

I would like to use handlebars.js or mustache.js to iterate over a list of families, and then iterate over that family's members. Inside of both loops, I want to display properties of both. However, once I get into the second iteration, none of the family variables are visible.

我想使用handlebars.js或mustache.js迭代一系列的系列,然后遍历该系列的成员。在两个循环内部,我想显示两者的属性。但是,一旦我进入第二次迭代,没有一个家庭变量是可见的。

{{#each families}}
  {{#each members}}
    <p>{{ ( here I want a family name property ) }}</p>
    <p>{{ ( here I want a member name property ) }}</p>
  {{/each}}
{{/each}}

Is this possible? I'd greatly appreciate any help!

这可能吗?我非常感谢任何帮助!

5 个解决方案

#1


44  

You can nest sections easily with lists of objects. Use a data structure where families is a list that has an object members that has a list of any objects (or even more lists)like:

您可以使用对象列表轻松嵌套节。使用数据结构,其中族是一个列表,其中的对象成员具有任何对象(甚至更多列表)的列表,如:

{
  "families" : [
        {
          "surname": "Jones",
          "members": [
            {"given": "Jim"},
            {"given": "John"},
            {"given": "Jill"}
          ]
        },
        {
          "surname": "Smith",
          "members": [
            {"given": "Steve"},
            {"given": "Sally"}
          ]
        }
      ]
}

You would be able to populate a template like:

您可以填充模板,如:

<ul>
    {{#families}}
    <li>{{surname}}
      <ul>
        {{#members}}
        <li>{{given}}</li>
        {{/members}}
      </ul>
    </li>
    {{/families}}
  </ul>

jsFiddle is currently down so here's the full working HTML with JS:

jsFiddle目前正在关闭所以这里是JS的完整工作HTML:

<!DOCTYPE html>
<head>

  <script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.3.0/mustache.min.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script>
    $(function() {
      var tpl = $('#fam').html(),
        data = {
          "families" : [
            {
              "surname": "Jones",
              "members": [
                {"given": "Jim"},
                {"given": "John"},
                {"given": "Jill"}
              ]
            },
            {
              "surname": "Smith",
              "members": [
                {"given": "Steve"},
                {"given": "Sally"}
              ]
            }
          ]
        },
        html = Mustache.to_html(tpl, data);

        $("#main").append(html);

    });
  </script>

</head>

<div id="main"></div>

<script type="template/text" id="fam">
  <ul>
    {{#families}}
    <li>{{surname}}
      <ul>
        {{#members}}
        <li>{{given}}</li>
        {{/members}}
      </ul>
    </li>
    {{/families}}
  </ul>
</script>

#2


52  

Sorry I'm a little late in the game here. The accepted answer is great but I wanted to add an answer that I think is also useful, especially if you are iterating over simple row/column arrays.

对不起,我在游戏中有点晚了。接受的答案很棒,但我想添加一个我认为也很有用的答案,特别是如果你在简单的行/列数组上进行迭代。

When you're working with nested handlebar paths, you can use ../ to refer to the parent template context (see here for more information).

当您使用嵌套的车把路径时,可以使用../来引用父模板上下文(有关详细信息,请参阅此处)。

So for your example, you could do:

所以对于你的例子,你可以这样做:

{{#each families}}
  {{#each members}}
    <p>{{../surname}}</p>
    <p>{{given}}</p>
  {{/each}}
{{/each}}

This was especially useful for me because I was making a grid and I wanted to give each square a class name corresponding to its row and column position. So if rows and columns, simply return arrays, I can do this:

这对我来说特别有用,因为我正在创建一个网格,我想给每个方块一个与其行和列位置相对应的类名。所以如果行和列只是返回数组,我可以这样做:

<tbody>
  {{#each rows}}                                                           
    <tr>
      {{#each columns}}
        <td class="{{this}}{{../this}}"></td>
      {{/each}}
    </tr>
  {{/each}}
</tbody>

Update

This solution is for Handlebars. A comment below explains why it will not work in Mustache.

此解决方案适用于Handlebars。下面的评论解释了为什么它不能用于Mustache。

#3


5  

Great answer @maxbeatty.

很棒的答案@maxbeatty。

I just wanted to add another example if anyone have the same problem and can't understand the above solution.

我只是想添加另一个例子,如果有人有同样的问题,无法理解上述解决方案。

First I have one dimensional array which I wanted to split on every 4 elements:

首先,我有一维数组,我想在每4个元素上拆分:

// this is the one dimensional data we have from let's say a mysql query
var array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', ...];

// think of it as [[], [], [], [], [], ...]
// but instead we'll be adding a dummy object with a dummyKey
// since we need a key to iterate on
var jagged = [];

var size = 4, // this is the size of each block
    total = array.length / block; // total count of all blocks
// slice the initial one dimensional array into blocks of 4 elements each
for (var i=0; i < total; i++) {
    jagged.push({dummyKey: array.slice(i*size, (i+1)*size)});
}

Now if we pass jagged into our view we can iterate it like that:

现在,如果我们将锯齿状传递到我们的视图中,我们可以像这样迭代它:

<ul>
{{#jagged}}
    <li>
        <ul>
            {{#dummyKey}}
            <li>{{.}}</li>
            {{/dummyKey}}
        </ul>
    </li>
{{/jagged}}
</ul>

If we have our initial array filled with objects:

如果我们的初始数组填充了对象:

var array = [{key1: 'a', 
              key2: 'b'},
             {key1: 'c', 
              key2: 'd'},
             {key1: 'e', 
              key2: 'f'},
              ...
];

Then in our template we'll have:

然后在我们的模板中我们将:

<ul>
{{#jagged}}
    <li>
        <ul>
            {{#dummyKey}}
            <li>{{key1}} - {{key2}}</li>
            {{/dummyKey}}
        </ul>
    </li>
{{/jagged}}
</ul>

#4


2  

For a dataset like below:

对于如下数据集:

{
  rows: 
    ["1A", "1B"], 
    ["2A", "2B"], 
    ["3A", "3B"]
}

following will work in mustachejs:

以下将在mustachejs中工作:

<tbody>
    {{#rows}}
    <tr>
        {{#.}}
        <td>{{.}}</td>
        {{/.}}
    </tr>
    {{/rows}}
</tbody>

#5


0  

I was looking for the same issue using mustache and the answers were given for handlebars, and the ones for mustache required extra JS, I know it is old but I'll add my working example just in case somebody else needs it. Cheers!

我一直在寻找使用小胡子的相同问题,并且给出了把手的答案,小胡子需要额外的JS,我知道它已经老了,但我会添加我的工作示例以防其他人需要它。干杯!

JSON:

"experience": [
     {
            "company": "Company 1",
            "position": "Graphic Designer",
            "tasks": ["Task 1", "Task 2", "Task 3"]
    },
     {
            "company": "Company 2",
            "position": "Graphic Designer",
            "tasks": ["Task 1", "Task 2", "Task 3", "Task 4", "Task 5"]
    }
]

TEMPLATE:

{{#experience}}
        <h2>{{company}}</h2>
        <div class="position">{{position}}</div>
        <div class="occupazione">Responsabilities</div>
            <ul>
            {{#tasks}}
            <li>{{.}}</li>
            {{/tasks}}
            </ul>
 {{/experience}}

#1


44  

You can nest sections easily with lists of objects. Use a data structure where families is a list that has an object members that has a list of any objects (or even more lists)like:

您可以使用对象列表轻松嵌套节。使用数据结构,其中族是一个列表,其中的对象成员具有任何对象(甚至更多列表)的列表,如:

{
  "families" : [
        {
          "surname": "Jones",
          "members": [
            {"given": "Jim"},
            {"given": "John"},
            {"given": "Jill"}
          ]
        },
        {
          "surname": "Smith",
          "members": [
            {"given": "Steve"},
            {"given": "Sally"}
          ]
        }
      ]
}

You would be able to populate a template like:

您可以填充模板,如:

<ul>
    {{#families}}
    <li>{{surname}}
      <ul>
        {{#members}}
        <li>{{given}}</li>
        {{/members}}
      </ul>
    </li>
    {{/families}}
  </ul>

jsFiddle is currently down so here's the full working HTML with JS:

jsFiddle目前正在关闭所以这里是JS的完整工作HTML:

<!DOCTYPE html>
<head>

  <script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.3.0/mustache.min.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script>
    $(function() {
      var tpl = $('#fam').html(),
        data = {
          "families" : [
            {
              "surname": "Jones",
              "members": [
                {"given": "Jim"},
                {"given": "John"},
                {"given": "Jill"}
              ]
            },
            {
              "surname": "Smith",
              "members": [
                {"given": "Steve"},
                {"given": "Sally"}
              ]
            }
          ]
        },
        html = Mustache.to_html(tpl, data);

        $("#main").append(html);

    });
  </script>

</head>

<div id="main"></div>

<script type="template/text" id="fam">
  <ul>
    {{#families}}
    <li>{{surname}}
      <ul>
        {{#members}}
        <li>{{given}}</li>
        {{/members}}
      </ul>
    </li>
    {{/families}}
  </ul>
</script>

#2


52  

Sorry I'm a little late in the game here. The accepted answer is great but I wanted to add an answer that I think is also useful, especially if you are iterating over simple row/column arrays.

对不起,我在游戏中有点晚了。接受的答案很棒,但我想添加一个我认为也很有用的答案,特别是如果你在简单的行/列数组上进行迭代。

When you're working with nested handlebar paths, you can use ../ to refer to the parent template context (see here for more information).

当您使用嵌套的车把路径时,可以使用../来引用父模板上下文(有关详细信息,请参阅此处)。

So for your example, you could do:

所以对于你的例子,你可以这样做:

{{#each families}}
  {{#each members}}
    <p>{{../surname}}</p>
    <p>{{given}}</p>
  {{/each}}
{{/each}}

This was especially useful for me because I was making a grid and I wanted to give each square a class name corresponding to its row and column position. So if rows and columns, simply return arrays, I can do this:

这对我来说特别有用,因为我正在创建一个网格,我想给每个方块一个与其行和列位置相对应的类名。所以如果行和列只是返回数组,我可以这样做:

<tbody>
  {{#each rows}}                                                           
    <tr>
      {{#each columns}}
        <td class="{{this}}{{../this}}"></td>
      {{/each}}
    </tr>
  {{/each}}
</tbody>

Update

This solution is for Handlebars. A comment below explains why it will not work in Mustache.

此解决方案适用于Handlebars。下面的评论解释了为什么它不能用于Mustache。

#3


5  

Great answer @maxbeatty.

很棒的答案@maxbeatty。

I just wanted to add another example if anyone have the same problem and can't understand the above solution.

我只是想添加另一个例子,如果有人有同样的问题,无法理解上述解决方案。

First I have one dimensional array which I wanted to split on every 4 elements:

首先,我有一维数组,我想在每4个元素上拆分:

// this is the one dimensional data we have from let's say a mysql query
var array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', ...];

// think of it as [[], [], [], [], [], ...]
// but instead we'll be adding a dummy object with a dummyKey
// since we need a key to iterate on
var jagged = [];

var size = 4, // this is the size of each block
    total = array.length / block; // total count of all blocks
// slice the initial one dimensional array into blocks of 4 elements each
for (var i=0; i < total; i++) {
    jagged.push({dummyKey: array.slice(i*size, (i+1)*size)});
}

Now if we pass jagged into our view we can iterate it like that:

现在,如果我们将锯齿状传递到我们的视图中,我们可以像这样迭代它:

<ul>
{{#jagged}}
    <li>
        <ul>
            {{#dummyKey}}
            <li>{{.}}</li>
            {{/dummyKey}}
        </ul>
    </li>
{{/jagged}}
</ul>

If we have our initial array filled with objects:

如果我们的初始数组填充了对象:

var array = [{key1: 'a', 
              key2: 'b'},
             {key1: 'c', 
              key2: 'd'},
             {key1: 'e', 
              key2: 'f'},
              ...
];

Then in our template we'll have:

然后在我们的模板中我们将:

<ul>
{{#jagged}}
    <li>
        <ul>
            {{#dummyKey}}
            <li>{{key1}} - {{key2}}</li>
            {{/dummyKey}}
        </ul>
    </li>
{{/jagged}}
</ul>

#4


2  

For a dataset like below:

对于如下数据集:

{
  rows: 
    ["1A", "1B"], 
    ["2A", "2B"], 
    ["3A", "3B"]
}

following will work in mustachejs:

以下将在mustachejs中工作:

<tbody>
    {{#rows}}
    <tr>
        {{#.}}
        <td>{{.}}</td>
        {{/.}}
    </tr>
    {{/rows}}
</tbody>

#5


0  

I was looking for the same issue using mustache and the answers were given for handlebars, and the ones for mustache required extra JS, I know it is old but I'll add my working example just in case somebody else needs it. Cheers!

我一直在寻找使用小胡子的相同问题,并且给出了把手的答案,小胡子需要额外的JS,我知道它已经老了,但我会添加我的工作示例以防其他人需要它。干杯!

JSON:

"experience": [
     {
            "company": "Company 1",
            "position": "Graphic Designer",
            "tasks": ["Task 1", "Task 2", "Task 3"]
    },
     {
            "company": "Company 2",
            "position": "Graphic Designer",
            "tasks": ["Task 1", "Task 2", "Task 3", "Task 4", "Task 5"]
    }
]

TEMPLATE:

{{#experience}}
        <h2>{{company}}</h2>
        <div class="position">{{position}}</div>
        <div class="occupazione">Responsabilities</div>
            <ul>
            {{#tasks}}
            <li>{{.}}</li>
            {{/tasks}}
            </ul>
 {{/experience}}