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