Reputation: 776
Is there a way to get positional index during iteration in ember.js?
{{#each itemsArray}}
{{name}}
{{/each}}
I'm looking for a way to have something like:
{{#each itemsArray}}
{{name}} - {{index}}th place.
{{/each}}
Update:
As per the comment by @ebryn the below code works without using a nested view for each item:
<script type="text/x-handlebars">
{{#collection contentBinding="App.peopleController"}}
Index {{contentIndex}}: {{content.name}} <br />
{{/collection}}
</script>
Although to have something like adjustedIndex, a nested view would be required.
Upvotes: 22
Views: 13208
Reputation: 9624
As of Ember 1.11.0, index
is an optional parameter in each
blocks:
{{#each items as |item index|}}
{{item.name}} is at index {{index}}
{{/each}}
Upvotes: 2
Reputation: 4121
It's old question but still gets a lot of hits. In the current version of Ember.JS one can use _view.contentIndex
to display current index inside the loop.
{{#each}}
Index: {{_view.contentIndex}}
{{/each}}
If you need an adjusted index (for instance starting from 1) then there is a possibility of creating reusable helper increment
Ember.Handlebars.registerBoundHelper('increment', function(integer) {
return integer + 1;
});
then you would use it in the following way
{{#each}}
Index: {{increment _view.contentIndex}}
{{/each}}
Update
Starting with ember 1.11 you can do as well
{{#each people as |person index|}}
Index: {{increment index}}
{{/each}}
Upvotes: 22
Reputation: 6309
Actually yes you can get the position of the current index using the {{each}} helper. You have to create a view for every item in a list and then use {{_parentView.contentIndex}}
.
<script type="text/x-handlebars">
{{#each App.peopleController}}
{{#view App.PersonView contentBinding="this"}}
Index {{_parentView.contentIndex}}: {{content.name}} {{adjustedIndex}} <br />
{{/view}}
{{/each}}
</script>
App = Ember.Application.create();
App.peopleController = Ember.ArrayController.create({
content: [ { name: 'Roy' }, { name: 'Mike' }, { name: 'Lucy' } ]
});
App.PersonView = Ember.View.extend(Ember.Metamorph, {
content: null,
// Just to show you can get the current index here too...
adjustedIndex: function() {
return this.getPath('_parentView.contentIndex') + 1;
}.property()
});
See this jsFiddle for a working example.
Upvotes: 9
Reputation: 1445
In RC6 CollectionView
provides contentIndex
propery for each rendered view of collection. Each
helper uses CollectionView
in its implementation so uou can access index in this way:
{{#each itemsArray}}
{{_view.contentIndex}}
{{/each}}
Upvotes: 9
Reputation: 2008
As of Ember 9.8 and pre-1.0 you can wrap the "contentIndex" with a view in order to get at the virtual parent (the {{#each}}). If you don't add the view, your context ends up being either the main template, an item in your list or whatever you manually set with your {{#with}}
. It is not impossible to get at the {{#each}}
from the JS side but it is a lot more of a pain flipping through those child views.
{{#each App.peopleController}}
{{#view}}
Index {{view._parentView.contentIndex}}: {{name}} <br />
{{/view}}
{{/each}}
...OR...
{{#each people in App.peopleController}}
{{#view}}
Index {{view._parentView.contentIndex}}: {{people.name}} <br />
{{/view}}
{{/each}}
Just in-case you would like a fiddler.
Note: You can create a view and do a this.get("_parentView.contentIndex")
to get at the index if you want to modify the number at all.
Upvotes: 6
Reputation: 4407
This isn't currently a feature of Handlebars or Ember.Handlebars
. We have contentIndex
available inside #collection
/Ember.CollectionView
. I think it's useful to support in #each
too. Please file an issue at the GitHub repository: https://github.com/emberjs/ember.js/issues
Upvotes: 4
Reputation: 708
I have modified a bit ud3323 solution using collection. Check here: http://jsfiddle.net/johngouf/WSwna/13/
<script type="text/x-handlebars">
{{#collection contentBinding="App.peopleController"}}
{{#view App.PersonView contentBinding="this"}}
Index {{_parentView.contentIndex}}: {{content.name}} {{adjustedIndex}} <br />
{{/view}}
{{/collection}}
</script>
App = Ember.Application.create();
App.peopleController = Ember.ArrayController.create({
content: [ { name: 'Roy' }, { name: 'Mike' }, { name: 'Lucy' } ]
});
App.PersonView = Ember.View.extend({
content: null,
// Just to show you can get the current index here too...
adjustedIndex: function() {
return this.getPath('_parentView.contentIndex') + 1;
}.property()
});
Upvotes: 1
Reputation: 747
I think you could probably do something like this too
//add index property to all each queries
Handlebars.registerHelper('each', function(context, block) {
var ret = "";
for(var i=0, j=context.length; i<j; i++) {
context[i].index = i;
ret = ret + block(context[i]);
}
return ret;
});
Upvotes: 0