Skip to content

Commit

Permalink
[FEATURE ember-htmlbars-each-with-index]
Browse files Browse the repository at this point in the history
this adds index as an optional second parameter to #each blocks
fixes #10158
  • Loading branch information
tim-evans committed Jan 7, 2015
1 parent 5f05ed3 commit eec721c
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 5 deletions.
16 changes: 16 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,19 @@ for a detailed explanation.
Exposes the basic internal stream implementation as `Ember.Stream`.

Added in [#9693](https://github.com/emberjs/ember.js/pull/9693)

* `ember-htmlbars-each-with-index`

Adds an optional second parameter to `{{each}}` block parameters that is the index of the item.

For example,

```handlebars
<ul>
{{#each people as |person index|}}
<li>{{index}}) {{person.name}}</li>
{{/each}}
</ul>
```

Added in [#10160](https://github.com/emberjs/ember.js/pull/10160)
3 changes: 2 additions & 1 deletion features.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"ember-routing-transitioning-classes": true,
"new-computed-syntax": null,
"ember-testing-checkbox-helpers": null,
"ember-metal-stream": null
"ember-metal-stream": null,
"ember-htmlbars-each-with-index": null
},
"debugStatements": [
"Ember.warn",
Expand Down
5 changes: 4 additions & 1 deletion packages/ember-htmlbars/lib/helpers/each.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,11 @@ function eachHelper(params, hash, options, env) {
params.length <= 1
);

if (options.template && options.template.blockParams) {
var blockParams = options.template && options.template.blockParams;

if (blockParams) {
hash.keyword = true;
hash.blockParams = blockParams;
}

Ember.deprecate(
Expand Down
26 changes: 26 additions & 0 deletions packages/ember-htmlbars/tests/helpers/each_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,32 @@ function testEachWithItem(moduleName, useBlockParams) {
equal(view.$().text(), "AdamSteve");
});
}

if (useBlockParams) {
if (Ember.FEATURES.isEnabled('ember-htmlbars-each-with-index')) {
test("the index is passed as the second parameter to #each blocks", function() {
expect(3);

var adam = { name: "Adam" };
view = EmberView.create({
controller: A([adam, { name: "Steve" }]),
template: templateFor('{{#each this as |person index|}}{{index}}. {{person.name}}{{/each}}', true)
});
runAppend(view);
equal(view.$().text(), "0. Adam1. Steve");

run(function() {
view.get('controller').unshiftObject({ name: "Bob" });
});
equal(view.$().text(), "0. Bob1. Adam2. Steve");

run(function() {
view.get('controller').removeObject(adam);
});
equal(view.$().text(), "0. Bob1. Steve");
});
}
}
}

testEachWithItem("{{#each foo in bar}}", false);
Expand Down
29 changes: 26 additions & 3 deletions packages/ember-views/lib/views/collection_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,36 @@ var CollectionView = ContainerView.extend({
item = content.objectAt(idx);

itemViewProps.content = item;
itemViewProps._blockArguments = [item];
itemViewProps.contentIndex = idx;

view = this.createChildView(itemViewClass, itemViewProps);

if (Ember.FEATURES.isEnabled('ember-htmlbars-each-with-index')) {
if (this.blockParams > 1) {
view._blockArguments = [item, view.getStream('_view.contentIndex')];
} else if (this.blockParams === 1) {
view._blockArguments = [item];
}
} else {
if (this.blockParams > 0) {
view._blockArguments = [item];
}
}

addedViews.push(view);
}

this.replace(start, 0, addedViews);

if (Ember.FEATURES.isEnabled('ember-htmlbars-each-with-index')) {
if (this.blockParams > 1) {
var childViews = this._childViews;
for (idx = start+added; idx < len; idx++) {
view = childViews[idx];
set(view, 'contentIndex', idx);
}
}
}
} else {
emptyView = get(this, 'emptyView');

Expand All @@ -381,9 +404,9 @@ var CollectionView = ContainerView.extend({
if (CoreView.detect(emptyView)) {
this._createdEmptyView = emptyView;
}
}

this.replace(start, 0, addedViews);
this.replace(start, 0, addedViews);
}
},

/**
Expand Down

0 comments on commit eec721c

Please sign in to comment.