Руль/усы - есть ли встроенный способ перебирать свойства объекта?
Как говорится в заголовке вопроса, существует ли способ зацикливания усов/рулей через Свойстваобъекта ?
Так же и с
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
}
?
7 ответов:
Встроенная поддержка начиная с рулей 1. 0rc1
Поддержка этой функциибыла добавлена к рулю.js, так что больше нет необходимости во внешних помощниках.
Как им пользоваться
Для массивов:
{{#each myArray}} Index: {{@index}} Value = {{this}} {{/each}}
Для объектов:
{{#each myObject}} Key: {{@key}} Value = {{this}} {{/each}}
Обратите внимание, что только свойства, передающие
hasOwnProperty
тест будет перечислен.
Это на самом деле довольно легко реализовать в качестве помощника:
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 }}
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] }); } }
Теперь ваш шаблон усов будет выглядеть примерно так:
{{#people}} {{key}} : {{value}} {{/people}}
Проверьте раздел "непустые списки" здесь: https://github.com/janl/mustache.js
Это ответ @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 }}
Ответ @ Amit хорош тем, что он будет работать как в усах, так и в руле.
Что касается решений только для рулей, я видел несколько, и мне нравится помощник блока
each_with_key
в https://gist.github.com/1371586 Самый лучший.
- это позволяет перебирать объектные литералы без необходимости их реструктуризации, и
Это дает вам контроль над тем, что вы называете ключевой переменной. Со многими другими решениями вы должны быть осторожны при использовании именованных ключей объектов'key'
, или'property'
и т. д.
Спасибо за решение Бена, мой вариант использования для отображения только определенных полей в порядке
С объектом
Код:
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
Это вспомогательная функция для 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
(порядок может быть случайным-это карта) Это может быть полезно, если вы знаете нужный элемент карты. Просто следите за ложными ценностями.