¿Cómo iterar sobre una matriz de objetos en Handlebars?

108

Esta puede parecer una pregunta tonta, pero parece que no puedo encontrar la respuesta en ninguna parte.

Estoy llegando a esta API web que devuelve una matriz de objetos en formato JSON:

matriz de objetos

Los documentos de Handlebars muestran el siguiente ejemplo:

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

En el contexto de:

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

En mi caso, no tengo un nombre para la matriz, es solo el objeto raíz de la respuesta. Intenté usarlo {{#each}}sin suerte.

Primera vez que uso Manillar ... ¿Qué me estoy perdiendo?

ACTUALIZAR

Aquí hay un violín simplificado para mostrarle lo que estoy preguntando: http://jsfiddle.net/KPCh4/2/

¿El manillar requiere que la variable de contexto sea un objeto y no una matriz?

emzero
fuente
¿Cómo se pasan los resultados de la API a la plantilla ( actualmente )?
Gabriele Petrioli
@ GabyakaG.Petrioli la API no es mía, no tengo control sobre ella. Solo estoy usando jQuery ajax y obtengo el objeto de respuesta, que es una matriz de objetos.
emzero

Respuestas:

156

Puedes pasar thisa cada bloque. Vea aquí: http://jsfiddle.net/yR7TZ/1/

{{#each this}}
    <div class="row"></div>
{{/each}}
ARIZONA.
fuente
Entonces, ¿es posible llamar al número de índice del bucle externo {{#each people}}dentro del bucle interno {{#each this}}? Me gusta{{people@index}}
RegarBoy
17

Este violín tiene eachjson directo y. http://jsfiddle.net/streethawk707/a9ssja22/ .

A continuación se muestran las dos formas de iterar sobre una matriz. Uno es con el paso directo de json y otro es nombrar la matriz json mientras se pasa al contenedor de contenido.

Eg1: El siguiente ejemplo está llamando directamente a la clave json (datos) dentro de la variable small_data.

En html use el siguiente código:

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

Lo siguiente se puede colocar en el encabezado o en el cuerpo de 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>

El siguiente está listo para el documento:

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

El siguiente es el json:

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

Finalmente adjunte el json al soporte de contenido:

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

Eg2: Iteración usando cada uno.

Considere el siguiente json.

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]" }
                  ]
            }
      ];

Al pasar el json al titular del contenido, simplemente nómbrelo de esta manera:

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

Y la plantilla se ve así:

<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>
halcón callejero
fuente
¿Cómo se compila esto usando manillares gulp?
webkitfanz
10

Quise decir en la template()llamada ..

Solo necesita pasar los resultados como un objeto. Entonces en lugar de llamar

var html = template(data);

hacer

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

y utilícelo {{#each apidata}}en su código de plantilla

demostración en http://jsfiddle.net/KPCh4/4/
( eliminó algunos ifcódigos sobrantes que fallaron )

Gabriele Petrioli
fuente
3
Eso es bueno, pero la respuesta AZ es mejor. Usar {{#each this}}es la forma correcta.
emzero
de hecho, de esta manera tiene mucho más sentido, ¡Gracias!
woohoo
8

Los manillares pueden usar una matriz como contexto. Puede utilizarlo .como raíz de los datos. Para que pueda recorrer los datos de su matriz con {{#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
fuente
1

Usando thisy {{this}}. Consulte el código a continuación en 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));

Salida del registro de la consola:

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