diff --git a/packages/@ember/-internals/runtime/lib/mixins/observable.js b/packages/@ember/-internals/runtime/lib/mixins/observable.js
index 4d5551cbc32..06c8e59cf5b 100644
--- a/packages/@ember/-internals/runtime/lib/mixins/observable.js
+++ b/packages/@ember/-internals/runtime/lib/mixins/observable.js
@@ -362,12 +362,12 @@ export default Mixin.create({
@param {String} key The key to observe
@param {Object} target The target object to invoke
@param {String|Function} method The method to invoke
- @param {Boolean} async Whether the observer is async or not
+ @param {Boolean} sync Whether the observer is sync or not
@return {Observable}
@public
*/
- addObserver(key, target, method, async) {
- addObserver(this, key, target, method, async);
+ addObserver(key, target, method, sync) {
+ addObserver(this, key, target, method, sync);
return this;
},
@@ -380,12 +380,12 @@ export default Mixin.create({
@param {String} key The key to observe
@param {Object} target The target object to invoke
@param {String|Function} method The method to invoke
- @param {Boolean} async Whether the observer is async or not
+ @param {Boolean} sync Whether the observer is async or not
@return {Observable}
@public
*/
- removeObserver(key, target, method, async) {
- removeObserver(this, key, target, method, async);
+ removeObserver(key, target, method, sync) {
+ removeObserver(this, key, target, method, sync);
return this;
},
diff --git a/packages/@ember/controller/lib/controller_mixin.js b/packages/@ember/controller/lib/controller_mixin.js
index 0fb0d4588ce..6d2ce5ae92b 100644
--- a/packages/@ember/controller/lib/controller_mixin.js
+++ b/packages/@ember/controller/lib/controller_mixin.js
@@ -1,7 +1,10 @@
-import { Mixin, tracked } from '@ember/-internals/metal';
+import { Mixin, computed } from '@ember/-internals/metal';
import { ActionHandler } from '@ember/-internals/runtime';
+import { symbol } from '@ember/-internals/utils';
import { EMBER_METAL_TRACKED_PROPERTIES } from '@ember/canary-features';
+const MODEL = symbol('MODEL');
+
/**
@module ember
*/
@@ -43,5 +46,13 @@ export default Mixin.create(ActionHandler, {
@property model
@public
*/
- model: EMBER_METAL_TRACKED_PROPERTIES ? tracked() : null,
+ model: computed({
+ get() {
+ return this[MODEL];
+ },
+
+ set(key, value) {
+ return (this[MODEL] = value);
+ },
+ }),
});
diff --git a/packages/@ember/controller/tests/controller_test.js b/packages/@ember/controller/tests/controller_test.js
index b28821de1f9..07193818367 100644
--- a/packages/@ember/controller/tests/controller_test.js
+++ b/packages/@ember/controller/tests/controller_test.js
@@ -3,7 +3,70 @@ import Service, { inject as injectService } from '@ember/service';
import { Object as EmberObject } from '@ember/-internals/runtime';
import { Mixin, get } from '@ember/-internals/metal';
import { runDestroy, buildOwner } from 'internal-test-helpers';
-import { moduleFor, AbstractTestCase } from 'internal-test-helpers';
+import { moduleFor, ApplicationTestCase, AbstractTestCase, runTask } from 'internal-test-helpers';
+import { action } from '@ember/object';
+
+moduleFor(
+ 'Controller model',
+ class extends ApplicationTestCase {
+ async '@test model is tracked'(assert) {
+ this.add(
+ 'controller:index',
+ class extends Controller {
+ constructor() {
+ super(...arguments);
+ this.model = 0;
+ }
+
+ get derived() {
+ return this.model + 1;
+ }
+
+ @action
+ update() {
+ this.model++;
+ }
+ }
+ );
+
+ this.addTemplate('index', '');
+
+ await this.visit('/');
+
+ this.assertText('1');
+
+ runTask(() => this.$('button').click());
+ this.assertText('2');
+ }
+
+ async '@test model can be observed with sync observers'(assert) {
+ let observerDidRun = false;
+
+ this.add(
+ 'controller:index',
+ class extends Controller {
+ constructor() {
+ super(...arguments);
+ this.model = 0;
+
+ this.addObserver('model', this, () => (observerDidRun = true), true);
+ }
+
+ @action
+ update() {
+ this.model++;
+ }
+ }
+ );
+
+ this.addTemplate('index', '');
+
+ await this.visit('/');
+ runTask(() => this.$('button').click());
+ assert.equal(observerDidRun, true, 'observer ran');
+ }
+ }
+);
moduleFor(
'Controller event handling',