Рулевое управление/Усы - Есть ли встроенный способ прокрутки свойств объекта?
Как говорится в заголовке вопроса, существует ли способ усов/ручек для циклического перехода через свойства объекта?
Итак,
var o = {
bob : 'For sure',
roger: 'Unknown',
donkey: 'What an ass'
}
Могу ли я затем что-то сделать в движке шаблона, который будет эквивалентен
for(var prop in o)
{
// with say, prop a variable in the template and value the property value
}
?
Ответы
Ответ 1
Встроенная поддержка с Handlebars 1.0rc1
Поддержка этой функциональности добавлена в Handlebars.js, поэтому больше нет необходимости в внешних помощниках.
Как использовать его
Для массивов:
{{#each myArray}}
Index: {{@index}} Value = {{this}}
{{/each}}
Для объектов:
{{#each myObject}}
Key: {{@key}} Value = {{this}}
{{/each}}
Обратите внимание, что будут перечислены только те свойства, которые проходят тест hasOwnProperty
.
Ответ 2
На самом деле довольно просто реализовать в качестве помощника:
Handlebars.registerHelper('eachProperty', function(context, options) {
var ret = "";
for(var prop in context)
{
ret = ret + options.fn({property:prop,value:context[prop]});
}
return ret;
});
Затем, используя его так:
{{#eachProperty object}}
{{property}}: {{value}}<br/>
{{/eachProperty }}
Ответ 3
EDIT: Handlebars теперь имеет встроенный способ выполнения этого; см. выбранный ответ выше.
При работе с равным Усыстом все еще применяется.
Усы могут перебирать элементы в массиве. Поэтому я бы предложил создать отдельный объект данных, отформатированный таким образом, чтобы Усы могли работать с:
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]
});
}
}
Теперь ваш шаблон Mustache будет примерно таким:
{{#people}}
{{key}} : {{value}}
{{/people}}
Ознакомьтесь с разделом "Непустые списки" здесь: https://github.com/janl/mustache.js
Ответ 4
Это ответ @Ben, обновленный для использования с Ember... обратите внимание, что вы должны использовать Ember.get
, потому что контекст передается как строка.
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;
});
Шаблон:
{{#eachProperty object}}
{{key}}: {{value}}<br/>
{{/eachProperty }}
Ответ 5
@Показать ответ хорошо, потому что он будет работать как в Усы, так и в Handlebars.
Что касается решений Handlebars, я видел несколько, и мне нравится вспомогательный блок each_with_key
в https://gist.github.com/1371586. лучше всего.
- Это позволяет вам перебирать литералы объектов, не перестраивая их сначала, и
- Он дает вам контроль над тем, что вы называете ключевой переменной. Со многими другими решениями вы должны быть осторожны с использованием объектных ключей с именем
'key'
или 'property'
и т.д.
Ответ 6
Спасибо за решение Ben, мой вариант использования для отображения только определенных полей в порядке
с объектом
код:
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;
});
Исходный объект:
{ locationDesc:"abc", name:"ghi", description:"def", four:"you wont see this"}
Шаблон:
{{#eachToDisplayProperty this "locationDesc,description,name"}}
<div>
{{property}} --- {{value}}
</div>
{{/eachToDisplayProperty}}
Вывод:
locationDesc --- abc
description --- def
name --- ghi
Ответ 7
Это вспомогательная функция для mustacheJS, без предварительного форматирования данных и вместо этого получения ее во время рендеринга.
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'
}
}
};
Шаблон:
{{#list}}
{{#.}}<span>color: {{#valueFromMap}}color{{/valueFromMap}}</span> <br/>{{/.}}
{{/list}}
Выходы:
color: blue
color: red
(порядок может быть случайным - это карта)
Это может быть полезно, если вы знаете нужный элемент карты. Просто следите за ложными значениями.