I have Ember.Object which is being used as a basic key/value dictionary. The names of the keys are dynamic and what I\'d like to be able do is iterate over these properties.
Here are some ideas.
Object's Keys method 1
You can iterate over the properties and filter out the keys from the prototype chain (using the hasOwnProperty() method):
var obj = App.MyObject.create({stuff: "stuff!"});
var objKeys = []
for(var key in obj) {
if(obj.hasOwnProperty(key)){
objKeys.push(key);
}
}
console.log(objKeys); // ['stuff']
Object's Keys method 2
On newer browsers you can directly get an array of the object's properties using the Object.keys() method:
console.log(Object.keys(obj)); // ['stuff']
Ember.Object's computed properties
Ember provides a way to iterate over the computed properties of a class using the eachComputedProperty() method
App.MyObject.eachComputedProperty(function(name, meta){
console.log(name, meta); // randomComputedProperty
});
JSBin example demonstrating these methods
Update
You could have a computed property on your model that re-arranges the MyObject
's data into an array which can then be displayed by handlebars:
App.MyModel = DS.Model.extend({
prop1: DS.attr('string'),
prop2: DS.attr('number'),
prop3: DS.attr('my-object'),
prop3PropertyArray: function(){
var prop3,
propertyArray = [];
prop3 = this.get('prop3');
for(var key in prop3) {
if(prop3.hasOwnProperty(key) && key !== "toString"){
propertyArray.push({key: key, value: prop3.get(key)});
}
}
return propertyArray;
}.property('prop3')
});
If prop3
contained:
prop3: App.MyObject.create({
stuff: "stuff!",
anotherRandomKey: "more value here"
})
then prop3PropertyArray
would be:
[
{
key: "stuff",
value: "stuff!"
},
{
key: "anotherRandomKey",
value: "more value here"
}
]
which can then be displayed in handlebars using an {{#each}}..{{/each}}
helper:
{{#each item in prop3PropertyArray}}
{{item.key}} = {{item.value}}<br>
{{/each}}
Updated JSBin example
In Ember v2.0.0-beta.1 you can use {{each-in}}
helper, which lets you to iterate over object keys and their values in your templates.
For example, sample object:
App.MyObject = Ember.Object.extend({
randomComputedProperty() {
return 'foobar';
}
});
Instantiated this way:
let $object = App.MyObject.create({
prop1: 'value1',
prop2: 'value2',
prop3: ['element1', 'element2']
});
And iterated over in template using {{each-in}}
helper:
{{#each-in $object as |key value|}}
`{{key}}`:`{{value}}`
{{/each-in}}
Produces following results:
`prop1`:`value1`
`prop2`:`value2`
`prop3`:`element1,element2`
JSBin demonstrating this.
It's worth to mention that using {{each-in}}
helper:
is a one time snapshot look at the object, it will not observe properties being added/removed/changed.
Thanks @Kingpin2k for pointing this out. Demo, note that update to prop1
isn't reflected in the DOM.