From eec721c572b75b3ed61c009bdf323e0a4c709554 Mon Sep 17 00:00:00 2001 From: Tim Evans Date: Tue, 6 Jan 2015 14:05:33 -0500 Subject: [PATCH] [FEATURE ember-htmlbars-each-with-index] this adds index as an optional second parameter to #each blocks fixes #10158 --- FEATURES.md | 16 ++++++++++ features.json | 3 +- packages/ember-htmlbars/lib/helpers/each.js | 5 +++- .../ember-htmlbars/tests/helpers/each_test.js | 26 +++++++++++++++++ .../ember-views/lib/views/collection_view.js | 29 +++++++++++++++++-- 5 files changed, 74 insertions(+), 5 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index a9161e6e1af..5a550baf2a2 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -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 + + ``` + + Added in [#10160](https://github.com/emberjs/ember.js/pull/10160) diff --git a/features.json b/features.json index 2c4da5336eb..4dcef8ecfd7 100644 --- a/features.json +++ b/features.json @@ -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", diff --git a/packages/ember-htmlbars/lib/helpers/each.js b/packages/ember-htmlbars/lib/helpers/each.js index d933956c2d6..763ce9ec31b 100644 --- a/packages/ember-htmlbars/lib/helpers/each.js +++ b/packages/ember-htmlbars/lib/helpers/each.js @@ -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( diff --git a/packages/ember-htmlbars/tests/helpers/each_test.js b/packages/ember-htmlbars/tests/helpers/each_test.js index 38f78199628..37d4ab40b50 100644 --- a/packages/ember-htmlbars/tests/helpers/each_test.js +++ b/packages/ember-htmlbars/tests/helpers/each_test.js @@ -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); diff --git a/packages/ember-views/lib/views/collection_view.js b/packages/ember-views/lib/views/collection_view.js index 43440d56d16..5c846c7cb16 100644 --- a/packages/ember-views/lib/views/collection_view.js +++ b/packages/ember-views/lib/views/collection_view.js @@ -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'); @@ -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); + } }, /**