diff --git a/packages/ember-htmlbars/tests/helpers/collection_test.js b/packages/ember-htmlbars/tests/helpers/collection_test.js
index 57f7a00b689..e0ca071614f 100644
--- a/packages/ember-htmlbars/tests/helpers/collection_test.js
+++ b/packages/ember-htmlbars/tests/helpers/collection_test.js
@@ -199,6 +199,7 @@ QUnit.test("empty views should be removed when content is added to the collectio
});
view = EmberView.create({
+ _viewRegistry: {},
listView: ListView,
listController: listController,
template: compile('{{#collection view.listView content=view.listController tagName="table"}}
{{view.content.title}} | {{/collection}}')
diff --git a/packages/ember-metal/lib/computed.js b/packages/ember-metal/lib/computed.js
index 3f0a348d945..34383b5d2bc 100644
--- a/packages/ember-metal/lib/computed.js
+++ b/packages/ember-metal/lib/computed.js
@@ -1,3 +1,4 @@
+import Ember from 'ember-metal/core';
import { set } from "ember-metal/property_set";
import {
meta,
@@ -251,6 +252,13 @@ ComputedPropertyPrototype.property = function() {
var args;
var addArg = function(property) {
+ Ember.deprecate(
+ `Depending on arrays using a dependent key ending with \`@each\` is deprecated. ` +
+ `Please refactor from \`Ember.computed('${property}', function() {});\` to \`Ember.computed('${property.slice(0, -6)}.[]', function() {})\`.`,
+ property.slice(-5) !== '@each',
+ { id: 'ember-metal.@each-dependent-key-leaf', until: '2.0.0' }
+ );
+
args.push(property);
};
diff --git a/packages/ember-metal/lib/mixin.js b/packages/ember-metal/lib/mixin.js
index 933d45fb17c..b5a7fee2a55 100644
--- a/packages/ember-metal/lib/mixin.js
+++ b/packages/ember-metal/lib/mixin.js
@@ -813,7 +813,16 @@ export function observer(...args) {
var func = args.slice(-1)[0];
var paths;
- var addWatchedProperty = function(path) { paths.push(path); };
+ var addWatchedProperty = function(path) {
+ Ember.deprecate(
+ `Depending on arrays using a dependent key ending with \`@each\` is deprecated. ` +
+ `Please refactor from \`Ember.observer('${path}', function() {});\` to \`Ember.computed('${path.slice(0, -6)}.[]', function() {})\`.`,
+ path.slice(-5) !== '@each',
+ { id: 'ember-metal.@each-dependent-key-leaf', until: '2.0.0' }
+ );
+
+ paths.push(path);
+ };
var _paths = args.slice(0, -1);
if (typeof func !== "function") {
diff --git a/packages/ember-metal/tests/computed_test.js b/packages/ember-metal/tests/computed_test.js
index 1885e320751..6e7e417d870 100644
--- a/packages/ember-metal/tests/computed_test.js
+++ b/packages/ember-metal/tests/computed_test.js
@@ -59,6 +59,16 @@ QUnit.test('defining computed property should invoke property on set', function(
equal(get(obj, 'foo'), 'computed bar', 'should return new value');
});
+QUnit.test('defining a computed property with a dependent key ending with @each is deprecated', function() {
+ expectDeprecation(function() {
+ computed('blazo.@each', function() { });
+ }, `Depending on arrays using a dependent key ending with \`@each\` is deprecated. Please refactor from \`Ember.computed('blazo.@each', function() {});\` to \`Ember.computed('blazo.[]', function() {})\`.`);
+
+ expectDeprecation(function() {
+ computed('qux', 'zoopa.@each', function() { });
+ }, `Depending on arrays using a dependent key ending with \`@each\` is deprecated. Please refactor from \`Ember.computed('zoopa.@each', function() {});\` to \`Ember.computed('zoopa.[]', function() {})\`.`);
+});
+
var objA, objB;
QUnit.module('computed should inherit through prototype', {
setup() {
diff --git a/packages/ember-runtime/lib/mixins/sortable.js b/packages/ember-runtime/lib/mixins/sortable.js
index d0a7f439c29..65a1f125e16 100644
--- a/packages/ember-runtime/lib/mixins/sortable.js
+++ b/packages/ember-runtime/lib/mixins/sortable.js
@@ -166,7 +166,7 @@ export default Mixin.create(MutableEnumerable, {
@property arrangedContent
@private
*/
- arrangedContent: computed('content', 'sortProperties.@each', {
+ arrangedContent: computed('content', 'sortProperties.[]', {
get(key) {
var content = get(this, 'content');
var isSorted = get(this, 'isSorted');
diff --git a/packages/ember-views/lib/views/select.js b/packages/ember-views/lib/views/select.js
index a2e38a488d0..e68680f0332 100644
--- a/packages/ember-views/lib/views/select.js
+++ b/packages/ember-views/lib/views/select.js
@@ -499,7 +499,7 @@ var Select = View.extend({
});
return groupedContent;
- }).property('optionGroupPath', 'content.@each'),
+ }).property('optionGroupPath', 'content.[]'),
/**
The view class for option.
@@ -519,7 +519,7 @@ var Select = View.extend({
}
},
- selectionDidChange: observer('selection.@each', function() {
+ selectionDidChange: observer('selection.[]', function() {
var selection = get(this, 'selection');
if (get(this, 'multiple')) {
if (!isArray(selection)) {
diff --git a/packages/ember-views/tests/views/view/child_views_test.js b/packages/ember-views/tests/views/view/child_views_test.js
index 23431d8d507..f05e1ee2be0 100644
--- a/packages/ember-views/tests/views/view/child_views_test.js
+++ b/packages/ember-views/tests/views/view/child_views_test.js
@@ -103,6 +103,10 @@ QUnit.test('should remove childViews inside {{if}} on destroy', function() {
run(outerView, 'set', 'value', false);
equal(outerView.get('childViews.length'), 0, 'expected no views to be leaked');
+
+ run(function() {
+ outerView.destroy();
+ });
});
QUnit.test('should remove childViews inside {{each}} on destroy', function() {
@@ -151,4 +155,8 @@ QUnit.test('should remove childViews inside {{each}} on destroy', function() {
run(outerView, 'set', 'value', false);
equal(outerView.get('childViews.length'), 0, 'expected no views to be leaked');
+
+ run(function() {
+ outerView.destroy();
+ });
});