Pergunta

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>​

http://jsfiddle.net/WSwna/14/

Although to have something like adjustedIndex, a nested view would be required.

Foi útil?

Solução

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}}

Outras dicas

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}}

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.

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.

DEMO

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.

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

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}}

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()
});

​​

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;
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top