javascript - property - object.keys map
Manubrios/Bigote: ¿existe una forma integrada de recorrer las propiedades de un objeto? (7)
Como dice el título de la pregunta, ¿hay una forma de bigote / manubrio de recorrer las propiedades de un objeto ?
Entonces con
var o = {
bob : ''For sure'',
roger: ''Unknown'',
donkey: ''What an ass''
}
¿Puedo hacer algo en el motor de plantillas que sea equivalente a
for(var prop in o)
{
// with say, prop a variable in the template and value the property value
}
?
Soporte integrado desde Handlebars 1.0rc1
El soporte para esta funcionalidad se ha agregado a Handlebars.js, por lo que ya no hay necesidad de ayudantes externos.
Cómo usarlo
Para matrices:
{{#each myArray}}
Index: {{@index}} Value = {{this}}
{{/each}}
Para objetos:
{{#each myObject}}
Key: {{@key}} Value = {{this}}
{{/each}}
Tenga en cuenta que solo se enumerarán las propiedades que pasen la prueba hasOwnProperty
.
En realidad es bastante fácil de implementar como ayudante:
Handlebars.registerHelper(''eachProperty'', function(context, options) {
var ret = "";
for(var prop in context)
{
ret = ret + options.fn({property:prop,value:context[prop]});
}
return ret;
});
Luego usándolo así:
{{#eachProperty object}}
{{property}}: {{value}}<br/>
{{/eachProperty }}
Esta es la respuesta de @ Ben actualizada para su uso con Ember ... tenga en cuenta que debe usar Ember.get
porque el contexto se transfiere como una cadena.
Ember.Handlebars.registerHelper(''eachProperty'', function(context, options) {
var ret = "";
var newContext = Ember.get(this, context);
for(var prop in newContext)
{
if (newContext.hasOwnProperty(prop)) {
ret = ret + options.fn({property:prop,value:newContext[prop]});
}
}
return ret;
});
Modelo:
{{#eachProperty object}}
{{key}}: {{value}}<br/>
{{/eachProperty }}
Esta es una función auxiliar para bigoteJS, sin formatear previamente los datos y obtenerlos durante el procesamiento.
var data = {
valueFromMap: function() {
return function(text, render) {
// "this" will be an object with map key property
// text will be color that we have between the mustache-tags
// in the template
// render is the function that mustache gives us
// still need to loop since we have no idea what the key is
// but there will only be one
for ( var key in this) {
if (this.hasOwnProperty(key)) {
return render(this[key][text]);
}
}
};
},
list: {
blueHorse: {
color: ''blue''
},
redHorse: {
color: ''red''
}
}
};
Modelo:
{{#list}}
{{#.}}<span>color: {{#valueFromMap}}color{{/valueFromMap}}</span> <br/>{{/.}}
{{/list}}
Productos:
color: blue
color: red
(el orden puede ser aleatorio, es un mapa) Esto podría ser útil si conoce el elemento de mapa que desea. Solo ten cuidado con los valores falsy.
Gracias por la solución de Ben, mi caso de uso para mostrar solo campos particulares en orden
con objeto
Código:
handlebars.registerHelper(''eachToDisplayProperty'', function(context, toDisplays, options) {
var ret = "";
var toDisplayKeyList = toDisplays.split(",");
for(var i = 0; i < toDisplayKeyList.length; i++) {
toDisplayKey = toDisplayKeyList[i];
if(context[toDisplayKey]) {
ret = ret + options.fn({
property : toDisplayKey,
value : context[toDisplayKey]
});
}
}
return ret;
});
Objeto fuente:
{ locationDesc:"abc", name:"ghi", description:"def", four:"you wont see this"}
Modelo:
{{#eachToDisplayProperty this "locationDesc,description,name"}}
<div>
{{property}} --- {{value}}
</div>
{{/eachToDisplayProperty}}
Salida:
locationDesc --- abc
description --- def
name --- ghi
La respuesta de @ Amit es buena porque funcionará en ambos, Bigote y Manubrios.
En cuanto a las soluciones exclusivas de Handlebars, he visto algunas y me gusta el each_with_key
en https://gist.github.com/1371586 lo mejor.
- Le permite iterar sobre literales de objetos sin tener que reestructurarlos primero, y
- Te da control sobre lo que llamas la variable clave. Con muchas otras soluciones, debe tener cuidado con el uso de claves de objeto denominadas
''key''
o''property''
, etc.
EDITAR: Handlebars ahora tiene una forma incorporada de lograr esto; ver la respuesta seleccionada arriba. Cuando se trabaja con Bigote normal, se aplica lo siguiente.
Bigote puede iterar sobre elementos en una matriz. Así que sugeriría crear un objeto de datos separado formateado de una manera en la que Moustache pueda trabajar:
var o = {
bob : ''For sure'',
roger: ''Unknown'',
donkey: ''What an ass''
},
mustacheFormattedData = { ''people'' : [] };
for (var prop in o){
if (o.hasOwnProperty(prop)){
mustacheFormattedData[''people''].push({
''key'' : prop,
''value'' : o[prop]
});
}
}
Ahora, su plantilla de bigote sería algo así como:
{{#people}}
{{key}} : {{value}}
{{/people}}
Consulte la sección "Listas no vacías" aquí: https://github.com/janl/mustache.js