Como iterar sobre a matriz de objetos em Handlebars?

108

Esta pode parecer uma pergunta boba, mas não consigo encontrar a resposta em lugar nenhum.

Estou acessando esta API da Web que retorna uma matriz de objetos no formato JSON:

matriz de objetos

A documentação do guiador mostra o seguinte exemplo:

<ul class="people_list">
  {{#each people}}
  <li>{{this}}</li>
  {{/each}}
</ul>

Dentro do contexto de:

{
  people: [
    "Yehuda Katz",
    "Alan Johnson",
    "Charles Jolley"
  ]
}

No meu caso, não tenho um nome para o array, é apenas o objeto raiz da resposta. Tentei usar {{#each}}sem sorte.

Primeira vez usando guiador ... O que estou perdendo?

ATUALIZAR

Aqui está um violino simplificado para mostrar o que estou pedindo: http://jsfiddle.net/KPCh4/2/

O guidão exige que a variável de contexto seja um objeto e não uma matriz?

emzero
fonte
Como você passa os resultados da API para o modelo ( atualmente )?
Gabriele Petrioli
@ GabyakaG.Petrioli a API não é minha, não tenho controle sobre ela. Estou apenas usando o jQuery ajax e obtendo o objeto de resposta, que é uma matriz de objetos.
emzero

Respostas:

156

Você pode passar thispara cada bloco. Veja aqui: http://jsfiddle.net/yR7TZ/1/

{{#each this}}
    <div class="row"></div>
{{/each}}
AZ.
fonte
Então, é possível chamar o número de índice do loop externo {{#each people}}dentro do loop interno {{#each this}}? Like{{people@index}}
RegarBoy
17

Este violino tem ambos eache json direto. http://jsfiddle.net/streethawk707/a9ssja22/ .

Abaixo estão as duas maneiras de iterar sobre o array. Um é com passagem json direta e outro está nomeando a matriz json enquanto passa para o portador de conteúdo.

Eg1: O exemplo abaixo está chamando diretamente a chave json (dados) dentro da variável small_data.

Em html, use o código abaixo:

<div id="small-content-placeholder"></div>

O seguinte pode ser colocado no cabeçalho ou corpo do html:

<script id="small-template" type="text/x-handlebars-template">
    <table>
        <thead>
            <th>Username</th>
            <th>email</th>
        </thead>
        <tbody>
            {{#data}}
                <tr>
                    <td>{{username}}
                    </td>
                    <td>{{email}}</td>
                </tr>
            {{/data}}
        </tbody>
    </table>
</script>

O abaixo está em documento pronto:

var small_source   = $("#small-template").html();
var small_template = Handlebars.compile(small_source);

O abaixo é o json:

var small_data = {
            data: [
                {username: "alan1", firstName: "Alan", lastName: "Johnson", email: "[email protected]" },
                {username: "alan2", firstName: "Alan", lastName: "Johnson", email: "[email protected]" }
            ]
        };

Por fim, anexe o json ao suporte de conteúdo:

$("#small-content-placeholder").html(small_template(small_data));

Ex. 2: Iteração usando cada um.

Considere o json abaixo.

var big_data = [
            {
                name: "users1",
                details: [
                    {username: "alan1", firstName: "Alan", lastName: "Johnson", email: "[email protected]" },
                    {username: "allison1", firstName: "Allison", lastName: "House", email: "[email protected]" },
                    {username: "ryan1", firstName: "Ryan", lastName: "Carson", email: "[email protected]" }
                  ]
            },
            {
                name: "users2",
                details: [
                    {username: "alan2", firstName: "Alan", lastName: "Johnson", email: "[email protected]" },
                    {username: "allison2", firstName: "Allison", lastName: "House", email: "[email protected]" },
                    {username: "ryan2", firstName: "Ryan", lastName: "Carson", email: "[email protected]" }
                  ]
            }
      ];

Ao passar o json para o detentor do conteúdo, apenas nomeie-o desta forma:

$("#big-content-placeholder").html(big_template({big_data:big_data}));

E o modelo se parece com:

<script id="big-template" type="text/x-handlebars-template">
    <table>
        <thead>
            <th>Username</th>
            <th>email</th>
        </thead>
        <tbody>
            {{#each big_data}}
                <tr>
                    <td>{{name}}
                            <ul>
                                {{#details}}
                                    <li>{{username}}</li>
                                    <li>{{email}}</li>
                                {{/details}}
                            </ul>
                    </td>
                    <td>{{email}}</td>
                </tr>
            {{/each}}
        </tbody>
    </table>
</script>
falcão de rua
fonte
Como alguém compila isso usando o guiador gulp?
webkitfanz
10

Eu quis dizer na template()ligação ..

Você só precisa passar os resultados como um objeto. Então, ao invés de ligar

var html = template(data);

Faz

var html = template({apidata: data});

e usar {{#each apidata}}em seu código de modelo

demonstração em http://jsfiddle.net/KPCh4/4/
( removeu algum ifcódigo restante que travou )

Gabriele Petrioli
fonte
3
Isso é bom, mas a resposta AZ é melhor. Usar {{#each this}}é a forma correta.
emzero
na verdade, dessa forma faz muito mais sentido, obrigado!
woohoo
8

Os guiadores podem usar uma matriz como contexto. Você pode usar .como raiz dos dados. Assim, você pode fazer um loop pelos dados do array com {{#each .}}.

var data = [
  {
    Category: "General",
    DocumentList: [
      {
        DocumentName: "Document Name 1 - General",
        DocumentLocation: "Document Location 1 - General"
      },
      {
        DocumentName: "Document Name 2 - General",
        DocumentLocation: "Document Location 2 - General"
      }
    ]
  },
  {
    Category: "Unit Documents",
    DocumentList: [
      {
        DocumentName: "Document Name 1 - Unit Documents",
        DocumentList: "Document Location 1 - Unit Documents"
      }
    ]
  },
  {
    Category: "Minutes"
  }
];

$(function() {
  var source = $("#document-template").html();
  var template = Handlebars.compile(source);
  var html = template(data);
  $('#DocumentResults').html(html);
});
.row {
  border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0/handlebars.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="DocumentResults">pos</div>
<script id="document-template" type="text/x-handlebars-template">
  <div>
  {{#each .}}
    <div class="row">
      <div class="col-md-12">
        <h2>{{Category}}</h2>
        {{#DocumentList}}
        <p>{{DocumentName}} at {{DocumentLocation}}</p>
        {{/DocumentList}}
      </div>
    </div>
  {{/each}}
  </div>
</script>

Emre Efendi
fonte
1

Usando thise {{this}}. Veja o código abaixo em node.js:

var Handlebars= require("handlebars");
var randomList= ["James Bond", "Dr. No", "Octopussy", "Goldeneye"];
var source= "<ul>{{#each this}}<li>{{this}}</li>{{/each}}</ul>";
var template= Handlebars.compile(source);
console.log(template(randomList));

Saída de registro do console:

<ul><li>James Bond</li><li>Dr. No</li><li>Octopussy</li><li>Goldeneye</li></ul>
Megatron
fonte