Skip to content

Commit

Permalink
Deprecate Ember.ObjectController.
Browse files Browse the repository at this point in the history
* Deprecate on `init` of `Ember.ObjectController`'s when not
  auto-generated.
* Deprecate on `get` of a proxied property.
* Deprecate on `set` of a proxied property.
  • Loading branch information
rwjblue committed Jan 2, 2015
1 parent d13a87b commit 33042d9
Show file tree
Hide file tree
Showing 15 changed files with 160 additions and 66 deletions.
2 changes: 1 addition & 1 deletion packages/ember-htmlbars/tests/helpers/each_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ function testEachWithItem(moduleName, useBlockParams) {
test("itemController specified in ArrayController with name binding does not change context", function() {
people = A([{ name: "Steve Holt" }, { name: "Annabelle" }]);

var PersonController = ObjectController.extend({
var PersonController = EmberController.extend({
controllerName: computed(function() {
return "controller:" + get(this, 'model.name') + ' of ' + get(this, 'parentController.company');
})
Expand Down
6 changes: 3 additions & 3 deletions packages/ember-htmlbars/tests/helpers/view_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import precompile from 'ember-htmlbars/compat/precompile';
import compile from "ember-template-compiler/system/compile";
import template from 'ember-template-compiler/system/template';
import { observersFor } from "ember-metal/observer";
import ObjectController from 'ember-runtime/controllers/object_controller';
import Controller from 'ember-runtime/controllers/controller';

import { runAppend, runDestroy } from "ember-runtime/tests/utils";
import { set } from 'ember-metal/property_set';
Expand Down Expand Up @@ -622,15 +622,15 @@ test('{{view}} should not override class bindings defined on a child view', func
something: 'visible'
});

registry.register('controller:label', ObjectController, { instantiate: true });
registry.register('controller:label', Controller, { instantiate: true });
registry.register('view:label', LabelView);
registry.register('template:label', compile('<div id="child-view"></div>'));
registry.register('template:nester', compile('{{render "label"}}'));

view = EmberView.create({
container: container,
templateName: 'nester',
controller: ObjectController.create({
controller: Controller.create({
container: container
})
});
Expand Down
16 changes: 12 additions & 4 deletions packages/ember-htmlbars/tests/helpers/with_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import EmberObject from "ember-runtime/system/object";
import { computed } from "ember-metal/computed";
import { set } from "ember-metal/property_set";
import { get } from "ember-metal/property_get";
import ObjectController from "ember-runtime/controllers/object_controller";
import {
default as ObjectController,
objectControllerDeprecation
} from "ember-runtime/controllers/object_controller";
import EmberController from 'ember-runtime/controllers/controller';
import { Registry } from "ember-runtime/system/container";
import compile from "ember-template-compiler/system/compile";
import { runAppend, runDestroy } from "ember-runtime/tests/utils";
Expand Down Expand Up @@ -212,6 +216,8 @@ test("it should support #with this as qux", function() {
QUnit.module("Handlebars {{#with foo}} with defined controller");

test("it should wrap context with object controller [DEPRECATED]", function() {
expectDeprecation(objectControllerDeprecation);

var Controller = ObjectController.extend({
controllerName: computed(function() {
return "controller:"+this.get('model.name') + ' and ' + this.get('parentController.name');
Expand Down Expand Up @@ -301,7 +307,9 @@ test("it should still have access to original parentController within an {{#each
});
*/

test("it should wrap keyword with object controller", function() {
test("it should wrap keyword with object controller [DEPRECATED]", function() {
expectDeprecation(objectControllerDeprecation);

var PersonController = ObjectController.extend({
name: computed('model.name', function() {
return get(this, 'model.name').toUpperCase();
Expand Down Expand Up @@ -355,7 +363,7 @@ test("it should wrap keyword with object controller", function() {

test("destroys the controller generated with {{with foo controller='blah'}} [DEPRECATED]", function() {
var destroyed = false;
var Controller = ObjectController.extend({
var Controller = EmberController.extend({
willDestroy: function() {
this._super();
destroyed = true;
Expand Down Expand Up @@ -391,7 +399,7 @@ test("destroys the controller generated with {{with foo controller='blah'}} [DEP

test("destroys the controller generated with {{with foo as bar controller='blah'}}", function() {
var destroyed = false;
var Controller = ObjectController.extend({
var Controller = EmberController.extend({
willDestroy: function() {
this._super();
destroyed = true;
Expand Down
9 changes: 4 additions & 5 deletions packages/ember-routing-htmlbars/tests/helpers/action_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import ActionManager from "ember-views/system/action_manager";
import { Registry } from "ember-runtime/system/container";
import EmberObject from "ember-runtime/system/object";
import { default as EmberController } from "ember-runtime/controllers/controller";
import EmberObjectController from "ember-runtime/controllers/object_controller";
import EmberArrayController from "ember-runtime/controllers/array_controller";

import compile from "ember-template-compiler/system/compile";
Expand Down Expand Up @@ -153,7 +152,7 @@ test("should target the current controller inside an {{each}} loop [DEPRECATED]"
registeredTarget = options.target.value();
};

var itemController = EmberObjectController.create();
var itemController = EmberController.create();

var ArrayController = EmberArrayController.extend({
itemController: 'stub',
Expand Down Expand Up @@ -187,7 +186,7 @@ test("should target the with-controller inside an {{#with controller='person'}}
registeredTarget = options.target.value();
};

var PersonController = EmberObjectController.extend();
var PersonController = EmberController.extend();
var registry = new Registry();
var container = registry.container();
var parentController = EmberObject.create({
Expand Down Expand Up @@ -693,7 +692,7 @@ test("should only trigger actions for the event they were registered on", functi
test("should unwrap controllers passed as a context", function() {
var passedContext;
var model = EmberObject.create();
var controller = EmberObjectController.extend({
var controller = EmberController.extend({
model: model,
actions: {
edit: function(context) {
Expand All @@ -717,7 +716,7 @@ test("should unwrap controllers passed as a context", function() {
test("should not unwrap controllers passed as `controller`", function() {
var passedContext;
var model = EmberObject.create();
var controller = EmberObjectController.extend({
var controller = EmberController.extend({
model: model,
actions: {
edit: function(context) {
Expand Down
24 changes: 11 additions & 13 deletions packages/ember-routing-htmlbars/tests/helpers/render_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
} from "ember-runtime/system/string";

import { default as EmberController } from "ember-runtime/controllers/controller";
import EmberObjectController from "ember-runtime/controllers/object_controller";
import EmberArrayController from "ember-runtime/controllers/array_controller";

import EmberRouter from "ember-routing/system/router";
Expand Down Expand Up @@ -54,7 +53,6 @@ function buildContainer(namespace) {
registry.register('location:hash', HashLocation);

registry.register('controller:basic', EmberController, { instantiate: false });
registry.register('controller:object', EmberObjectController, { instantiate: false });
registry.register('controller:array', EmberArrayController, { instantiate: false });

registry.typeInjection('route', 'router', 'router:main');
Expand Down Expand Up @@ -202,10 +200,10 @@ test("{{render}} helper should render given template with a supplied model", fun
template: compile(template)
});

var PostController = EmberObjectController.extend();
var PostController = EmberController.extend();
container._registry.register('controller:post', PostController);

Ember.TEMPLATES['post'] = compile("<p>{{title}}</p>");
Ember.TEMPLATES['post'] = compile("<p>{{model.title}}</p>");

appendView(view);

Expand Down Expand Up @@ -238,7 +236,7 @@ test("{{render}} helper with a supplied model should not fire observers on the c
template: compile(template)
});

var PostController = EmberObjectController.extend({
var PostController = EmberController.extend({
modelDidChange: observer('model', function() {
modelDidChange++;
})
Expand Down Expand Up @@ -324,10 +322,10 @@ test("{{render}} helper should render templates with models multiple times", fun
template: compile(template)
});

var PostController = EmberObjectController.extend();
var PostController = EmberController.extend();
container._registry.register('controller:post', PostController, { singleton: false });

Ember.TEMPLATES['post'] = compile("<p>{{title}}</p>");
Ember.TEMPLATES['post'] = compile("<p>{{model.title}}</p>");

appendView(view);

Expand Down Expand Up @@ -366,7 +364,7 @@ test("{{render}} helper should not leak controllers", function() {
template: compile(template)
});

var PostController = EmberObjectController.extend();
var PostController = EmberController.extend();
container._registry.register('controller:post', PostController);

Ember.TEMPLATES['post'] = compile("<p>{{title}}</p>");
Expand All @@ -391,7 +389,7 @@ test("{{render}} helper should not treat invocations with falsy contexts as cont
template: compile(template)
});

var PostController = EmberObjectController.extend();
var PostController = EmberController.extend();
container._registry.register('controller:post', PostController, { singleton: false });

Ember.TEMPLATES['post'] = compile("<p>{{#unless model}}NOTHING{{/unless}}</p>");
Expand Down Expand Up @@ -424,10 +422,10 @@ test("{{render}} helper should render templates both with and without models", f
template: compile(template)
});

var PostController = EmberObjectController.extend();
var PostController = EmberController.extend();
container._registry.register('controller:post', PostController, { singleton: false });

Ember.TEMPLATES['post'] = compile("<p>Title:{{title}}</p>");
Ember.TEMPLATES['post'] = compile("<p>Title:{{model.title}}</p>");

appendView(view);

Expand Down Expand Up @@ -519,7 +517,7 @@ test("{{render}} works with dot notation", function() {
var template = '<h1>BLOG</h1>{{render "blog.post"}}';

var controller = EmberController.extend({ container: container });
container._registry.register('controller:blog.post', EmberObjectController.extend());
container._registry.register('controller:blog.post', EmberController.extend());

view = EmberView.create({
controller: controller.create(),
Expand All @@ -539,7 +537,7 @@ test("{{render}} works with slash notation", function() {
var template = '<h1>BLOG</h1>{{render "blog/post"}}';

var controller = EmberController.extend({ container: container });
container._registry.register('controller:blog.post', EmberObjectController.extend());
container._registry.register('controller:blog.post', EmberController.extend());

view = EmberView.create({
controller: controller.create(),
Expand Down
6 changes: 4 additions & 2 deletions packages/ember-routing/tests/system/controller_for_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import Registry from 'container/registry';
import Namespace from "ember-runtime/system/namespace";
import { classify } from "ember-runtime/system/string";
import Controller from "ember-runtime/controllers/controller";
import ObjectController from "ember-runtime/controllers/object_controller";
import {
default as ObjectController
} from "ember-runtime/controllers/object_controller";
import ArrayController from "ember-runtime/controllers/array_controller";
import controllerFor from "ember-routing/system/controller_for";
import {
Expand Down Expand Up @@ -95,7 +97,7 @@ test("generateController should create Ember.Controller", function() {
ok(controller instanceof Controller, 'should create controller');
});

test("generateController should create Ember.ObjectController", function() {
test("generateController should create Ember.ObjectController [DEPRECATED]", function() {
var context = {};
var controller = generateController(container, 'home', context);

Expand Down
11 changes: 10 additions & 1 deletion packages/ember-runtime/lib/controllers/object_controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import Ember from 'ember-metal/core';
import ControllerMixin from 'ember-runtime/mixins/controller';
import ObjectProxy from 'ember-runtime/system/object_proxy';

export var objectControllerDeprecation = 'Ember.ObjectController is deprected, ' +
'please use Ember.Controller and use `model.propertyName`.';

/**
@module ember
@submodule ember-runtime
Expand All @@ -18,5 +22,10 @@ import ObjectProxy from 'ember-runtime/system/object_proxy';
@namespace Ember
@extends Ember.ObjectProxy
@uses Ember.ControllerMixin
@deprecated
**/
export default ObjectProxy.extend(ControllerMixin);
export default ObjectProxy.extend(ControllerMixin, {
init: function() {
Ember.deprecate(objectControllerDeprecation, this.isGenerated);
}
});
11 changes: 11 additions & 0 deletions packages/ember-runtime/lib/mixins/-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ export default Mixin.create({
unknownProperty: function (key) {
var content = get(this, 'content');
if (content) {
Ember.deprecate(
fmt('You attempted to access `%@` from `%@`, but object proxying is deprecated. ' +
'Please use `model.%@` instead.', [key, this, key]),
!this.isController
);
return get(content, key);
}
},
Expand All @@ -89,6 +94,12 @@ export default Mixin.create({
var content = get(this, 'content');
Ember.assert(fmt("Cannot delegate set('%@', %@) to the 'content' property of" +
" object proxy %@: its 'content' is undefined.", [key, value, this]), content);

Ember.deprecate(
fmt('You attempted to set `%@` from `%@`, but object proxying is deprecated. ' +
'Please use `model.%@` instead.', [key, this, key]),
!this.isController
);
return set(content, key, value);
}

Expand Down
7 changes: 6 additions & 1 deletion packages/ember-runtime/tests/controllers/controller_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import Controller from "ember-runtime/controllers/controller";
import Service from "ember-runtime/system/service";
import ObjectController from "ember-runtime/controllers/object_controller";
import {
default as ObjectController,
objectControllerDeprecation
} from "ember-runtime/controllers/object_controller";
import Mixin from "ember-metal/mixin";
import Object from "ember-runtime/system/object";
import { Registry } from "ember-runtime/system/container";
Expand Down Expand Up @@ -55,6 +58,8 @@ test("When `_actions` is provided, `actions` is left alone", function() {
});

test("Actions object doesn't shadow a proxied object's 'actions' property", function() {
expectDeprecation(objectControllerDeprecation);

var TestController = ObjectController.extend({
model: {
actions: 'foo'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {computed} from "ember-metal/computed";
import compare from "ember-runtime/compare";
import EmberObject from "ember-runtime/system/object";
import ArrayController from "ember-runtime/controllers/array_controller";
import ObjectController from "ember-runtime/controllers/object_controller";
import Controller from "ember-runtime/controllers/controller";
import {sort} from "ember-runtime/computed/reduce_computed_macros";
import Registry from "container/registry";

Expand All @@ -25,7 +25,7 @@ QUnit.module("Ember.ArrayController - itemController", {
lannisters = Ember.A([tywin, jaime, cersei]);

itemControllerCount = 0;
controllerClass = ObjectController.extend({
controllerClass = Controller.extend({
init: function() {
++itemControllerCount;
this._super();
Expand All @@ -36,7 +36,7 @@ QUnit.module("Ember.ArrayController - itemController", {
}
});

otherControllerClass = ObjectController.extend({
otherControllerClass = Controller.extend({
toString: function() {
return "otherItemController for " + this.get('name');
}
Expand Down Expand Up @@ -305,7 +305,7 @@ test("array observers can invoke `objectAt` without overwriting existing item co
lannistersWillChange: function() { return this; },
lannistersDidChange: function(_, idx, removedAmt, addedAmt) {
arrayObserverCalled = true;
equal(this.objectAt(idx).get('name'), "Tyrion", "Array observers get the right object via `objectAt`");
equal(this.objectAt(idx).get('model.name'), "Tyrion", "Array observers get the right object via `objectAt`");
}
});
arrayController.addArrayObserver(arrayController, {
Expand All @@ -318,7 +318,7 @@ test("array observers can invoke `objectAt` without overwriting existing item co
});

equal(arrayObserverCalled, true, "Array observers are called normally");
equal(tywinController.get('name'), "Tywin", "Array observers calling `objectAt` does not overwrite existing controllers' model");
equal(tywinController.get('model.name'), "Tywin", "Array observers calling `objectAt` does not overwrite existing controllers' model");
});

test("`itemController`'s life cycle should be entangled with its parent controller", function() {
Expand All @@ -342,7 +342,7 @@ QUnit.module('Ember.ArrayController - itemController with arrayComputed', {
jaime = EmberObject.create({ name: 'Jaime' });
lannisters = Ember.A([jaime, cersei]);

controllerClass = ObjectController.extend({
controllerClass = Controller.extend({
title: computed(function () {
switch (get(this, 'name')) {
case 'Jaime': return 'Kingsguard';
Expand Down Expand Up @@ -374,5 +374,5 @@ test("item controllers can be used to provide properties for array computed macr
sorted: sort('@this', 'sortProperties')
});

deepEqual(arrayController.get('sorted').mapProperty('name'), ['Jaime', 'Cersei'], "ArrayController items can be sorted on itemController properties");
deepEqual(arrayController.get('sorted').mapProperty('model.name'), ['Jaime', 'Cersei'], "ArrayController items can be sorted on itemController properties");
});
Loading

0 comments on commit 33042d9

Please sign in to comment.