From 28de0fdb0e27eb65afc65dd71f5a030a5956d209 Mon Sep 17 00:00:00 2001 From: Sivakumar Kailasam Date: Wed, 21 Feb 2018 01:23:04 +0530 Subject: [PATCH] Use the new deprecation app --- app.json | 3 + source/deprecations/ember-cli/v2.x.html.md | 125 -- source/deprecations/ember-data/v2.x.html.md | 699 ------- source/deprecations/index.html.md | 27 - .../instance-initializers.html.md | 118 -- source/deprecations/v1.x.html.md | 1635 ----------------- source/deprecations/v2.x.html.md | 1111 ----------- source/deprecations/v3.x.html.md | 153 -- source/layouts/deprecations.erb | 11 - .../stylesheets/pages/deprecations.css.scss | 20 - source/stylesheets/site.css.scss | 1 - static.json | 3 + 12 files changed, 6 insertions(+), 3900 deletions(-) delete mode 100644 source/deprecations/ember-cli/v2.x.html.md delete mode 100644 source/deprecations/ember-data/v2.x.html.md delete mode 100644 source/deprecations/index.html.md delete mode 100644 source/deprecations/instance-initializers.html.md delete mode 100644 source/deprecations/v1.x.html.md delete mode 100644 source/deprecations/v2.x.html.md delete mode 100644 source/deprecations/v3.x.html.md delete mode 100644 source/layouts/deprecations.erb delete mode 100644 source/stylesheets/pages/deprecations.css.scss diff --git a/app.json b/app.json index 5857ac4dd4..d40f769b7b 100644 --- a/app.json +++ b/app.json @@ -3,6 +3,9 @@ "scripts": { }, "env": { + "DEPRECATION_APP_URL": { + "required": true + }, "EMBER_API_DOCS_URL": { "required": true }, diff --git a/source/deprecations/ember-cli/v2.x.html.md b/source/deprecations/ember-cli/v2.x.html.md deleted file mode 100644 index 41d98b0530..0000000000 --- a/source/deprecations/ember-cli/v2.x.html.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Deprecations for Ember CLI v2.x -alias: guides/deprecations/ -layout: deprecations -responsive: true ---- - -## Deprecations Added in Ember CLI 2.x - -### Deprecations Present in Ember CLI 2.0.0 - -#### Migrate from Brocfile.js to ember-cli-build.js - -###### until: 3.0.0 -###### id: cli.brocfile - -Early versions of Ember CLI utilized the default build file of Broccoli: `Brocfile.js`. Over time -we began realizing that this was not a tenable solution (we could not pass high fidelity objects -into the build pipeline, and therefore created two instances of all addons, etc), and introduced a -replacement for `Brocfile.js`: `ember-cli-build.js`. The new structure allows Ember CLI to pass -information into the function exported by `ember-cli-build.js` and avoid the issues mentioned above. - -The migration from `Brocfile.js` to `ember-cli-build.js` is fairly straight forward: - -Migrate `Brocfile.js` from: -```js -// Brocfile.js -var EmberApp = require('ember-cli/lib/broccoli/ember-app'); -var app = new EmberApp(); -module.exports = app.toTree(); -``` - -To `ember-cli-build.js`: - -```js -var EmberApp = require('ember-cli/lib/broccoli/ember-app'); - -module.exports = function(defaults) { - var app = new EmberApp(defaults, { - // Any options - }); - - return app.toTree(); -}; -``` - -### Deprecations Added in Ember CLI 2.2.0 - -#### Deprecate Utility - -###### until: 3.0.0 -###### id: cli.ui.deprecate - -Using the `ember-cli/lib/utlities/deprecate` module to issue deprecations has been deprecated -in favor of using `.writeDeprecateLine` method on the `ui` object (which is available on both -addons and project instances). - -Migrate from: - -```js -const deprecate = require('ember-cli/lib/utilities/deprecate'); - -module.exports = { - name: 'my-addon-name', - - someMethod() { - deprecate('this thing is deprecated!'); - } -} -``` - -To: - -```js -module.exports = { - name: 'my-addon-name', - - someMethod() { - this.ui.writeDeprecateLine('this thing is deprecated!'); - } -} -``` - -### Deprecations Added in Ember CLI 2.7.0 - -#### Base URL - -###### until: 3.0.0 -###### id: cli.baseURL - -The usage of `baseURL` setting in `config/environments.js` has been deprecated in favor of using -an explicit `rootURL`. A detailed explanation of the problem and the migration path can be found in -[this blog post](/blog/2016/04/28/baseURL.html). - -Migration for pre-2.7 applications is: - -1. Update `config/environment.js` to remove reference to `baseURL` and update to `rootURL`. -2. Update `app/index.html` to add `{{rootURL}}` a the beginning of all assets that are loaded. -3. Update the `app/router.js` to pass `rootURL` to the subclass of `Ember.Router` being created. - -More detailed descriptions of this migration can be found on the blog: [here](/blog/2016/04/28/baseURL.html) - -### Deprecations Added in Ember CLI 2.12.0 - -#### Clobbering Addon#options - -Clobbering `this.options` within an addon has been deprecated. If you would like to use `this.options` -for internal options within your addon, you must preserve the intitial options object that is present. - -Instead of doing this: - -```js -included() { - this.options = { my-addons: { special: { options: 'here' } } }; -} -``` - -You should do the following: - -```js -included() { - this.options = this.options || {}; - this.options['my-addons'] = { special: { options: 'here' } }; -} -``` diff --git a/source/deprecations/ember-data/v2.x.html.md b/source/deprecations/ember-data/v2.x.html.md deleted file mode 100644 index c8a8781bcf..0000000000 --- a/source/deprecations/ember-data/v2.x.html.md +++ /dev/null @@ -1,699 +0,0 @@ ---- -title: Deprecations for Ember Data v2.x -alias: guides/deprecations/ -layout: deprecations -responsive: true ---- - -## Deprecations Added in Ember Data 2.x - -### Deprecations Added in Ember Data 2.3 - -#### Non-primitive defaultValue for Model Attributes - -###### until: 3.0.0 -###### id: ds.defaultValue.complex-object - -Providing a non-primitive value as a `defaultValue` has been deprecated because -the provided value is shared between all instances of the model. Using a -non-primitive value, such as `defaultValue: []`, can lead to unexpected bugs when -that value is mutated. - -If you wish to continue using a non-primitive value as the `defaultValue` for an -attribute, you should provide a function that returns the value: - -```javascript -import DS from 'ember-data'; - -export default DS.Model.extend({ - username: DS.attr('string'), - createdAt: DS.attr('date', { - defaultValue() { - return new Date(); - } - }) -}); -``` - -#### RESTSerializer.keyForPolymorphicType - -###### until: 3.0.0 -###### id: ds.rest-serializer.deprecated-key-for-polymorphic-type - -Previous versions of the -[`RESTSerializer`](http://emberjs.com/api/data/classes/DS.RESTSerializer.html) -relied on -[`keyForAttribute`](http://emberjs.com/api/data/classes/DS.RESTSerializer.html#method_keyForAttribute) -to determine the type key used for serializing polymorphic relationships. This -behavior has been deprecated in favor of using -[`keyForPolymorphicType`](http://emberjs.com/api/data/classes/DS.RESTSerializer.html#method_keyForPolymorphicType). -The benefit of having this additional hook is that you can customize the type -key separately from the key used for the relationship. - -For example, given the following model: - -```app/models/comment.js -import DS from 'ember-data'; - -export default DS.Model.extend({ - commentable: belongsTo('commentable', { polymorphic: true }), - body: DS.attr('string') -}); -``` - -When using the `RESTSerializer`, Ember Data expects a payload that looks similar -the following: - -```javascript -{ - "comment": { - "id": "1", - "commentable": "123", - "commentableType": "movie", // ${keyForAttribute}Type - "body": "I'll be back" - }, - "movie": { - "id": "123", - "title": "The Terminator" - } -} -``` - -If your API instead responds with a key that doesn't follow the pattern of -`${keyForAttribute}Type`: - -```javascript -{ - "comment": { - "id": "1", - "commentable": "123", - "commentKind": "movie", // custom keyForPolymorphicType needed - "body": "I'll be back" - }, - "movie": { - "id": "123", - "title": "The Terminator" - } -} -``` - -You can now override the `keyForPolymorphicType` hook in your serializer to -accommodate: - -```javascript -import DS from 'ember-data'; - -export default DS.RESTSerializer.extend({ - keyForPolymorphicType: function() { - return 'commentKind'; - } -}); -``` - -### Deprecations Added in Ember Data 2.6 - -#### RESTSerializer.normalizeHash - -###### until: 3.0.0 -###### id: ds.serializer.normalize-hash-deprecated - -`RESTSerializer.normalizeHash` has been deprecated in favor of using `normalize`. - -If you had this: - -```javascript -import DS from 'ember-data'; - -export default DS.RESTSerializer.extend({ - normalizeHash: { - _id: function(hash) { - hash.id = hash._id; - delete hash._id; - return hash; - } - } -}); -``` - -You could change it to this: - -```javascript -import DS from 'ember-data'; - -export default DS.RESTSerializer.extend({ - normalize(model, hash, prop) { - if (prop === 'comments') { - hash.id = hash._id; - delete hash._id; - } - return this._super(...arguments); - } -}); -``` - -### Deprecations Added in Ember Data 2.7 - -#### Global version of DS - -###### until: 3.0.0 -###### id: ember-data.global-ds - -Using the global version of DS is deprecated. Import `DS` or specific modules from `ember-data` where needed. - -For example, if you had: - -```javascript -/* globals DS */ -``` - -It would be refactored to: - -```javascript -import DS from 'ember-data'; -``` - -#### Ember.Date.parse - -###### until: 3.0.0 -###### id: ds.ember.date.parse-deprecate - -`Ember.Date.parse` was created as a [progressive enhancement for ISO -8601](https://github.com/csnover/js-iso8601) support in browsers that do not -support it (Safari 5-, IE 8-, Firefox 3.6-). These browsers versions are no -longer supported by Ember or Ember Data so `Ember.Date.parse` has been -deprecated. - -To clear this deprecation you should refactor your application's code to use -`Date.parse` instead of `Ember.Date.parse`. - -#### Date Prototype Extension - -###### until: 3.0.0 -###### id: ds.date.parse-deprecate - -In previous versions of Ember Data, the native `Date.parse` function was -replaced with `Ember.Date.parse`, a [progressive enhancement for ISO -8601](https://github.com/csnover/js-iso8601) support in browsers that do not -support it (Safari 5-, IE 8-, Firefox 3.6-). Since these browser versions are no -longer supported by Ember or Ember data, this behavior has been deprecated. - -To clear this deprecation, you should disable Ember Data's `Date` prototype -extension. - -With Ember >= v2.7.0, disable the prototype extension for `Date`: - -```config/environment.js -ENV = { - EmberENV: { - EXTEND_PROTOTYPES: { - Date: false - } - } -} -``` - -With Ember < v2.7.0, values must be provided for all prototype extensions: - -```config/environment.js -var ENV = { - EmberENV: { - EXTEND_PROTOTYPES: { - Array: true, - Date: false, - Function: true, - String: true - } - } -}; -``` - -If you're not sure which prototype extensions your app already has enabled, you -can check `EmberENV.EXTEND_PROTOTYPES` in your browser's JavaScript console -while your app is running. - -See [Disabling Prototype -Extensions](https://guides.emberjs.com/v2.10.0/configuring-ember/disabling-prototype-extensions/#toc_strings) -for more information about how Ember uses prototype extensions. - -#### Store.queryRecord Array Response with RESTSerializer - -###### until: 3.0.0 -###### id: ds.serializer.rest.queryRecord-array-response - -When using -[`DS.RESTSerializer`](http://emberjs.com/api/data/classes/DS.RESTSerializer.html) -with previous versions of Ember Data, -[`store.queryRecord`](http://emberjs.com/api/data/classes/DS.Store.html#method_queryRecord) -provided support for normalizing payloads containing an array of primary data. -This behavior has been deprecated because it is basically the same as using -[`store.query`](http://emberjs.com/api/data/classes/DS.Store.html#method_query) -and returning the first model. - -Deprecated payload example with an array as the primary data: - -```js -// GET /users?username="GummyBear" - -{ - "users": [{ - "id": "1", - "username": "GummyBear" - }] -} -``` - -Expected payload example with a single object as the primary data: - -```js -// GET /users?username="GummyBear" - -{ - "user": { - "id": "1", - "username": "GummyBear", - } -} -``` - -If you need to support an API that responds with an array as the primary data, -you have a few options. The simplest option is to use -[`store.query`](http://emberjs.com/api/data/classes/DS.Store.html#method_query) -instead of -[`store.queryRecord`](http://emberjs.com/api/data/classes/DS.Store.html#method_queryRecord): - -```javascript -this.store.query('user', { username: 'GummyBear' }).then((users) => { - return users.objectAt(0); -}); -``` - -Another option is to override -[`normalizeQueryRecordResponse`](http://emberjs.com/api/data/classes/DS.RESTSerializer.html#method_normalizeQueryRecordResponse) -in your serializer, manipulating the payload so it matches the expected format: - -```app/serializers/user.js -import DS from 'ember-data'; - -export default DS.RESTSerializer.extend({ - normalizeQueryRecordResponse(store, primaryModelClass, payload) { - if (payload.users) { - payload.user = payload.users[0]; - delete payload.users; - } - - return this._super(...arguments); - } -}); -``` - -Another option is to customize the URL of the request made by -[`store.queryRecord`](http://emberjs.com/api/data/classes/DS.Store.html#method_queryRecord) -so that it makes a request that returns the expected payload with a single -object as its primary data. This can be done by overriding -[`urlForQueryRecord`](http://emberjs.com/api/data/classes/DS.RESTAdapter.html#method_urlForQueryRecord) -in your adapter: - -```app/adapters/user.js -import DS from 'ember-data'; - -export default DS.RESTAdapter.extend({ - urlForQueryRecord() { - let baseURL = this.buildURL(); - return `${baseURL}/user-query`; - } -}); -``` - -### Deprecations Added in Ember Data 2.11 - -#### recordIsLoaded - -###### until: 3.0.0 -###### id: ds.store.recordIsLoaded - -`recordIsLoaded` has been deprecated and is an alias for `hasRecordForId`, which should be used instead. - -If you have this: - -```javascript -store.recordIsLoaded('post', 1); // false -store.findRecord('post', 1).then(function() { - store.recordIsLoaded('post', 1); // true -}); -``` - -You can change it to this: - -```javascript -store.hasRecordForId('post', 1); // false -store.findRecord('post', 1).then(function() { - store.hasRecordForId('post', 1); // true -}); -``` - -#### lookupAdapter - -###### until: 3.0.0 -###### id: ds.store.lookupAdapter - -`lookupAdapter` has been deprecated in favor of using `adapterFor`. - -#### lookupSerializer - -###### until: 3.0.0 -###### id: ds.store.lookupSerializer - -`lookupSerializer` has been deprecated in favor of using `serializerFor`. - -#### Store.serialize - -###### until: 3.0.0 -###### id: ds.store.serialize - -`Store.serialize` has been deprecated in favor of -[`Model.serialize`](http://emberjs.com/api/data/classes/DS.Model.html#method_serialize) -as part of an effort to reduce duplication and API surface area. - -Before: - -```javascript -let post = this.store.peekRecord('post', 123); -this.store.serialize(post); -``` - -After: - -```javascript -let post = this.store.peekRecord('post', 123); - -post.serialize(); -``` - -### Deprecations Added in Ember Data 2.12 - -#### JSONSerializer.shouldSerializeHasMany - -###### until: 3.0.0 -###### id: ds.serializer.private-should-serialize-has-many - -The private method `_shouldSerializeHasMany` has been promoted to the public -API. To remove this deprecation, please remove the underscore to use the public -[`shouldSerializeHasMany`](http://emberjs.com/api/data/classes/DS.JSONSerializer.html#method_shouldSerializeHasMany) -method. - -### Deprecations Added in Ember Data 2.13 - -#### Unused Initializers - -###### until: 3.0.0 -###### id: ds.deprecated-initializers - -The Ember Data initializers `data-adapter`, `injectStore`, `transforms`, and `store` are no longer used, so they are being removed. -Applications that depend on these for the ordering of their own custom initializers can substitute `ember-data` instead, without any change in functionality. - -Before: - -```javascript -export function initialize(application) { - // ... your code ... -}; - -export default { - name: 'websocketInit', - after: 'store', - initialize: initialize -}; -``` - -After: - -```javascript -export function initialize(application) { - // ... your code ... -}; - -export default { - name: 'websocketInit', - after: 'ember-data', - initialize: initialize -}; -``` - -### Deprecations Added in Pending Features - -#### HasManyReference.push(array) - -###### until: 4.0.0 -###### id: ds.references.has-many.push-array -###### feature: ds-overhaul-references - -Passing an array to a `HasManyReference#push` has been deprecated. You should -refactor your code to instead pass a [JSON API Relationship -Object](http://jsonapi.org/format/#document-resource-object-relationships). - -For example, if you previously had something like: - -```javascript -let commentsData = [ - { data: { type: 'comment', id: 1 } }, - { data: { type: 'comment', id: 2 } } -]; - -let post = this.store.peekRecord('post', 123); - -post.hasMany('comments').push(commentsData); -``` - -You could remove this deprecation by refactoring your code to: - -```javascript -let commentsData = { - data: [ - { type: 'comment', id: 1 }, - { type: 'comment', id: 2 } - ] -}; - -let post = this.store.peekRecord('post', 123); - -post.hasMany('comments').push(commentsData); -``` - -#### HasManyReference.push Invalid Data - -###### until: 4.0.0 -###### id: ds.references.has-many.push-invalid-json-api -###### feature: ds-overhaul-references - -In previous versions of Ember Data, `HasManyReference#push` supported pushing -data that was almost formatted as a [JSON API Relationship -Object](http://jsonapi.org/format/#document-resource-object-relationships), but -wasn't quite correct. Pushing data that is formatted this way has been -deprecated. You should refactor your code to instead push a properly formatted -JSON API Relationship Object. - -For example, if you previously had something like: - -```javascript -let commentsData = { - data: [ - { data: { type: 'comment', id: 1 } }, - { data: { type: 'comment', id: 2 } } - ] -}; - -let post = this.store.peekRecord('post', 123); - -post.hasMany('comments').push(commentsData); -``` - -You could remove this deprecation by refactoring your code to: - -```javascript -let commentsData = { - data: [ - { type: 'comment', id: 1 }, - { type: 'comment', id: 2 } - ] -}; - -let post = this.store.peekRecord('post', 123); - -post.hasMany('comments').push(commentsData); -``` - -#### BelongsToReference.push(DS.Model) - -###### until: 4.0.0 -###### id: ds.references.belongs-to.push-record -###### feature: ds-overhaul-references - -Passing an instance of -[`DS.Model`](http://emberjs.com/api/data/classes/DS.Model.html) to -`BelongsToReference#push` has been deprecated. You should instead follow the -pattern of `model.set('relationship', value)` to update a `belongsTo` -relationship with an instance of `DS.Model`. - -For example, if you have something like: - -```javascript -let post = this.store.peekRecord('post', 123); -let author = this.store.peekRecord('user', 456); - -post.belongsTo('author').push(author); -``` - -You can remove this deprecation by refactoring your code to: - -```javascript -let post = this.store.peekRecord('post', 123); -let author = this.store.peekRecord('user', 456); - -post.set('author', author); -``` - -#### JSONAPISerializer.modelNameFromPayloadKey for Resource - -###### until: 4.0.0 -###### id: ds.json-api-serializer.deprecated-model-name-for-resource -###### feature: ds-payload-type-hooks - -Using `JSONAPISerializer.modelNameFromPayloadKey` to normalize the type of a -resource has been deprecated in favor of -`JSONAPISerializer.modelNameFromPayloadType`. - -In the context of a JSON API payload, it is the value of the `type` key that -maps to the name of the corresponding `DS.Model` class rather than the key that -the data is nested under. - -For example, if your API responds with a namespaced resource type in the payload -when you fetch a `post`: - -```javascript -// GET /post/1 - -{ - "data": { - "type": "api::v1::post", - "id": "1" - } -} -``` - -Previously, you would want to override `modelNameFromPayloadKey` to remove the -namespace: - -```app/serializers/post.js -import DS from 'ember-data'; - -export default DS.JSONAPISerializer.extend({ - modelNameFromPayloadKey(key) { - return key.replace('api::v1::', ''); - } -}); -``` - -You can remove this deprecation by refactoring your serializer to instead use -`modelNameFromPayloadType`: - -```app/serializers/post.js -import DS from 'ember-data'; - -export default DS.JSONAPISerializer.extend({ - modelNameFromPayloadType(type) { - return type.replace('api::v1::', ''); - } -}); -``` - -#### JSONAPISerializer.modelNameFromPayloadKey for Relationship - -###### until: 4.0.0 -###### id: ds.json-api-serializer.deprecated-model-name-for-relationship -###### feature: ds-payload-type-hooks - -Using `JSONAPISerializer.modelNameFromPayloadKey` to normalize the type of a -relationship has been deprecated in favor of -`JSONAPISerializer.modelNameFromPayloadType`. - -See [JSONAPISerializer.modelNameFromPayloadKey for -Resource](#toc_jsonapiserializer-modelnamefrompayloadkey-for-resource) for more -information. - -#### JSONAPISerializer.payloadKeyFromModelName for Resource - -###### until: 4.0.0 -###### id: ds.json-api-serializer.deprecated-payload-type-for-model -###### feature: ds-payload-type-hooks - -Using `JSONAPISerializer.payloadKeyFromModelName` to serialize the type of a -model has been deprecated in favor of -[`JSONAPISerializer.payloadTypeFromModelName`](http://emberjs.com/api/data/classes/DS.JSONAPISerializer.html#method_payloadTypeFromModelName). - -For example, if your API expects a namespaced resource type in the payload that -is sent when you create a `post` model: - -```javascript -// POST /api/posts/1 - -{ - "data": { - "id": 1, - "type": "api::v1::post" - } -} -``` - -Previously, you would want to override `payloadKeyFromModelName` to add the -namespace to the `modelName`: - -```app/serializers/post.js -import DS from 'ember-data'; - -export default DS.JSONAPISerializer.extend({ - payloadKeyFromModelName(modelName) { - return `api::v1::${modelName}`; - } -}); -``` - -You can remove this deprecation by refactoring your serializer to instead use -[`payloadTypeFromModelName`](http://emberjs.com/api/data/classes/DS.JSONAPISerializer.html#method_payloadTypeFromModelName): - -```app/serializers/post.js -import DS from 'ember-data'; - -export default DS.JSONAPISerializer.extend({ - payloadTypeFromModelName(modelName) { - return `api::v1::${modelName}`; - } -}); -``` - -#### JSONAPISerializer.payloadKeyFromModelName for belongsTo Relationship - -###### until: 4.0.0 -###### id: ds.json-api-serializer.deprecated-payload-type-for-belongs-to -###### feature: ds-payload-type-hooks - -Using `JSONAPISerializer.payloadKeyFromModelName` to serialize the type of a -`belongsTo` relationship has been deprecated in favor of -[`JSONAPISerializer.payloadTypeFromModelName`](http://emberjs.com/api/data/classes/DS.JSONAPISerializer.html#method_payloadTypeFromModelName). - -See [JSONAPISerializer.payloadKeyFromModelName for -Resource](#toc_jsonapiserializer-payloadkeyfrommodelname-for-resource) for more -information. - -#### JSONAPISerializer.payloadKeyFromModelName for hasMany Relationship - -###### until: 4.0.0 -###### id: ds.json-api-serializer.deprecated-payload-type-for-has-many -###### feature: ds-payload-type-hooks - -Using `JSONAPISerializer.payloadKeyFromModelName` to serialize the type of a -`hasMany` relationship has been deprecated in favor of -[`JSONAPISerializer.payloadTypeFromModelName`](http://emberjs.com/api/data/classes/DS.JSONAPISerializer.html#method_payloadTypeFromModelName). - -See [JSONAPISerializer.payloadKeyFromModelName for -Resource](#toc_jsonapiserializer-payloadkeyfrommodelname-for-resource) for more -information. diff --git a/source/deprecations/index.html.md b/source/deprecations/index.html.md deleted file mode 100644 index 6972a0c5f4..0000000000 --- a/source/deprecations/index.html.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Deprecations -responsive: true ---- - -## Deprecations - -Periodically, various APIs in Ember.js may be deprecated. During a minor -release, for instance when upgrading from version 1.9 to 1.10, you may see new -deprecations fire in your codebase. Until a major revision such as 2.0 lands, -code firing such deprecations is still supported by the Ember community. After -the next major revision lands, the supporting code may be removed. This style -of change management is commonly referred to as [Semantic Versioning](http://semver.org/). - -### Ember - -* [Version 1.x](/deprecations/v1.x) -* [Version 2.x](/deprecations/v2.x) -* [Version 3.x](/deprecations/v3.x) - -### Ember Data - -* [Version 2.x](/deprecations/ember-data/v2.x) - -### Ember CLI - -* [Version 2.x](/deprecations/ember-cli/v2.x) diff --git a/source/deprecations/instance-initializers.html.md b/source/deprecations/instance-initializers.html.md deleted file mode 100644 index d3e72ea96d..0000000000 --- a/source/deprecations/instance-initializers.html.md +++ /dev/null @@ -1,118 +0,0 @@ -## Deprecate Access to Instance Initializers - -When we initially designed Ember, we only had the use case of apps that -run in the browser in mind. In that world, you would load your app and -then it would run until the user closed the tab or navigated away. - -For testing, we quickly realized that we would need some way to "reset" -the application between each test without reloading the page and -starting from scratch. To that end, we isolated all of the state in an -application into an object called the container that could be thrown -away after each test had completed. - -We wanted a shared way for both apps and add-ons to initialize -applications when they booted and loaded. In particular, it was -important for people to get access to that container to make objects -available to the app at runtime. To do so, we introduced the initializer -API. - -For example, Ember Data uses this API to ensure that all of your -controllers and routes have access to the store object. - -As we have been working on the FastBoot effort to allow Ember apps to -run on the server, we realized that the assumption that there would only -be one instance of the app running at once no longer held. - -In particular, we realized that "app boot" was actually two distinct -phases: - -1. Loading all of your application code and registering objects with the - application (such as the store in the Ember Data example) -2. Instantiating objects when the app starts running - -When the application boots up for the first time, we need to run Step 1 -above, but it would be wasteful to run it for every request going to -your FastBoot server. - -We also realized that a huge number of real-world initializers were -simply registering classes and injections, while a smaller fraction of -initializers are doing work that truly needs to be done per run. - -By separating out these two kinds of work, we could improve the -performance of cases where a single application was used multiple times, -each with a fresh set of state. - -This applies to FastBoot, of course, but it also applies to integration -tests. Today, integration tests spend time executing code in -initializers that don't change between test runs, simply because of the -possibility that the initializer may also set up instances. - -Thankfully, the `initializer` infrastructure already clearly marks the -boot-up phase of your application (both in your own code and in -add-ons), so we only need to make a small tweak to `initializer`s for -FastBoot to work. - -This change makes the difference between initializers that set up code -and initializers that set up instances explicit. - -The old `App.initializer` API now receives a `registry`, which can be -freely used to set up code using the `register` API and the various -`inject` APIs. - -A new `App.instanceInitializer` API receives an `ApplicationInstance` -object. When migrating code, the most important property on the -`ApplicationInstance` is `container`, which you can use to get new -instances and set state on them. - -Migrating code to the new structure is fairly mechanical. Change code -that looks like: - -```js -App.initializer({ - name: "clock", - - initialize: function(container) { - container.register("clock:main", Clock); - var clock = container.lookup("clock:main"); - clock.setStartTime(Date.now()); - } -}); -``` - -To: - -```js -App.initializer({ - name: "clock", - - initialize: function(registry) { - registry.register("clock:main", Clock); - } -}); - -App.instanceInitializer({ - name: "clock", - - initialize: function(instance) { - var clock = instance.container.lookup("clock:main"); - clock.setStartTime(Date.now()); - } -}); -``` - -Some things to remember: - -1. All `instanceInitializer`s run after `initializer`s and do not share a - namespace. You can use the same name in both, and don't have to use - `before` or `after` to make sure that instance initializers run - second. -2. The deprecated `registry.lookup` works by maintaining a 1:1 mapping - between Application and a default `ApplicationInstance`. This is - fundamentally incompatible with FastBoot, and you will need to clear - this deprecation warning before you will be able to use any of the - FastBoot features. - -While FastBoot and the improved testing performance have not yet landed, -these changes allow us to continue work on those APIs after Ember 2.0. -It also future-proofs Ember for more situations where a single -`Application` has multiple runs over its lifetime. diff --git a/source/deprecations/v1.x.html.md b/source/deprecations/v1.x.html.md deleted file mode 100644 index cd8ebac281..0000000000 --- a/source/deprecations/v1.x.html.md +++ /dev/null @@ -1,1635 +0,0 @@ ---- -title: Deprecations for v1.x -alias: guides/deprecations/ -layout: deprecations -responsive: true ---- - -## Deprecations Added in Ember 1.x - -What follows is a list of deprecations introduced to Ember.js during the 1.x -cycle. - -For more information on deprecations in Ember, see the [main deprecations page] -(/deprecations). - -### Deprecations Added in 1.7 - -#### Observing container views like arrays. - -ContainerViews have been observable as arrays, where the items in -the array are childViews. This introduces complexity into container -views despite the feature being a rarely used one. - - -#### Ember.DeferredMixin and Ember.Deferred. - -`Ember.DeferredMixin` and `Ember.Deferred` have been deprecated in favor -of using `RSVP.Promise`s. - - -#### `.then` on Ember.Application. - -As part of the `Ember.DeferredMixin` deprecation, using `.then` on an -Ember.Application instance itself has been deprecated. - -You can use the `ready` hook or initializers to defer/advance readiness -instead. - -### Deprecations Added in 1.8 - -#### Global lookup of views - -Previous to Ember 1.8, views would commonly be fetched from the global -scope: - -```handlebars -{{view App.SomeView}} -{{each item in items itemViewClass=App.SomeView}} -``` - -Since Ember 1.8, views are more appropriately resolved on the application -via strings: - -```handlebars -{{view "some"}} -{{each item in items itemViewClass="some"}} -``` - -They may also be fetched via a binding: - -```handlebars -{{view view.someViewViaTheCurrentView}} -{{each itemViewClass=someViewViaAControllerProperty}} -``` - -In general, it is recommended that your Ember application avoid accessing -globals from a template. - -##### New usage of Ember.Select - -Most of Ember's provided views are already accessed via helpers. For example, -the [Ember.TextField](/api/classes/Ember.TextField.html) view is used via the -[input helper](/api/classes/Ember.Handlebars.helpers.html#method_input). - -The [Ember.Select](/api/classes/Ember.Select.html) view has not been upgraded to -have a helper. Instead, it was suggested that you call it via the global -class name: - -```handlebars -{{view Ember.Select content=manyItems}} -``` - -Since this lookup is now deprecated, the select view has been registered -on an application as `select`. The new usage is: - -```handlebars -{{view "select" content=manyItems}} -``` - -See the updated [Ember.Select](/api/classes/Ember.Select.html) documentation -and the [built-in views guide](/guides/views/built-in-views) for more details -and examples. - -##### Ember.js libraries and plugins - -If the code triggering this deprecation is being fired from a library, that -library may need to update its suggested usage. - -One solution for such a library is to provide mixins instead of classes: - -```js -// usage is {{view "list"}} -var App.ListView = Ember.View.extend(ListView); -``` - -A more advanced solution is to use an initializer to register the plugin's -views on the application: - -```js -// usage is {{view "list"}} -Ember.Application.initializer({ - name: 'list-view', - initialize: function(container, application) { - container.register('view:list', ListView); - } -}); -``` - -More details on how to register an Ember.js framework component are available -in the [initializer API documentation](/api/classes/Ember.Application.html#toc_initializers) -and the [dependency injection guide](/guides/understanding-ember/dependency-injection-and-service-lookup). - -#### Hash Location Paths Without Leading Slashes. - -Prior to this release, if you were using `location: 'hash'` (which is the default), you were able to link to a route with a `location.hash` that didn't contain the expected leading forward slash. e.g. `#foo` instead of the correct `#/foo`. Very few, if any, should be impacted by this since the router always produces the correct form. - -Doing so is ambiguous because you may also be trying to link to an element on the page whose id matches `
` and it also erroneously will create an extra history state if a user clicks on something that transitions to that route again, since it will change `location.hash === '#/foo'`. - -This ability will be removed quickly to allow us to mimic the browser's behavior of scrolling the page to an element whose id matches, but in our case doing so after the transition ends and everything is rendered. Once this feature is added, you'll be able to link to id's even with doubled up hashes: `#/foo#some-id` as well as the expected `#some-id`. - -### Deprecations Added in 1.9 - -#### More Consistent Handlebars Scope - -In Ember 1.9, the `each` and `with` helpers come in two flavors: a "context-switching" flavor and a "named-parameter" flavor. - -```handlebars -{{#each post in posts}} - {{!-- the context in here is the same as the outside context, - and `post` references the current iteration --}} -{{/each}} - -{{#each posts}} - {{!-- the context in here has shifted to the individual post. - the outer context is no longer accessible --}} -{{/each}} - -{{#with post as otherPost}} - {{!-- the context in here is the same as the outside context }} -{{/with}} - -{{#with post}} - {{!-- the context in here has shifted to the post. - the outer context is no longer accessible --}} -{{/with}} -``` - -This has proven to be one of the more confusing parts of the Ember templating system. It is also not clear to -beginners which to use, and when they choose the context-shifting form, they lose access to values in the outer -context that may be important. - -Because the helper itself offers no clue about the context-shifting behavior, it is easy (even for more experienced -Ember developers) to get confused when skimming a template about which object a value refers to. - -The context-shifting forms of `#each` and `#with` have been deprecated in favor of the named-parameter forms. In Ember 1.12, the `in` and `as` syntax are further deprecated in favor of block params syntax. See the [deprecation notes for in](/deprecations/v1.x/#toc_code-in-code-syntax-for-code-each-code) and [deprecation notes for as](/deprecations/v1.x/#toc_code-in-code-syntax-for-code-each-code). - -##### Transition Plan - -To transition your code to the new syntax, you can change templates that look like this: - -```handlebars -{{#each people}} -

{{firstName}} {{lastName}}

-

{{address}}

-{{/each}} -``` - -with: - -```handlebars -{{#each person in people}} -

{{person.firstName}} {{person.lastName}}

-

{{person.address}}

-{{/each}} -``` - -In preparation for further work on HTMLBars, the context switching form of `{{each}}` is deprecated. This is mostly a "mechanical" refactor and dramatically -simplifies how to think about the context in your templates. This change should be entirely mechanical. - -In prior versions you may have done one of the following: - -```handlebars - -``` - -```handlebars - -``` - -You should now be using: - -```handlebars - -``` - -```handlebars - -``` - -### Deprecations Added in 1.11 - -#### ObjectController - -Experienced Ember users have enjoyed the use of proxying behavior in -the `Ember.ObjectController` class since 1.0. However, this behavior -will be removed in Ember 2.0 as the framework migrates to routable components. - -New users hit three road bumps when learning about the object controller pattern. - -* Given a certain model, which of the three controller options should I be using? -* Which controller is generated by the framework if I do not specify one? -* When using an object controller, why should the `this` context not be passed - to actions if it has the properties of my model? - -For these reasons, the [Road to Ember 2.0 RFC](https://github.com/emberjs/rfcs/pull/15) -listed object controllers as a concept to be removed from the framework. - -To migrate from an explicitly defined object controller, first convert -the class definition to inherit from `Ember.Controller`. For example: - -```js -import Ember from "ember"; - -// Change: -export default Ember.ObjectController.extend({ -// To: -export default Ember.Controller.extend({ - -// ... -``` - -Next update any use of `{{modelPropertyName}}` in templates with `{{model.modelPropertyName}}`. -You should also review any computed property dependent keys, observer keys, and `get` and `set` -statements on the route and controller. An example of how to make this migration can -be found [in this PR to the Ghost project](https://github.com/TryGhost/Ghost/pull/4748). - -If a controller is not explicitly defined, but instead is being auto-generated -by the framework, it will only throw a deprecation message if the proxying -behavior is being used. - -Added in [PR #10062](https://github.com/emberjs/ember.js/pull/10062). - - -#### Access to Instances in Initializers - -Previously, initializers had access to an object that allowed them to -both register new classes and get instances of those classes. - -If you have an initializer that gets instances of a class, you need to -change it to use an instance initializer. - -Change code that looks like this: - -```js -App.initializer({ - name: "clock", - - initialize: function(container, application) { - application.register("clock:main", Clock); - var clock = container.lookup("clock:main"); - clock.setStartTime(Date.now()); - } -}); -``` - -To: - -```js -App.initializer({ - name: "clock", - - initialize: function(registry, application) { - application.register("clock:main", Clock); - } -}); - -App.instanceInitializer({ - name: "clock", - - initialize: function(instance) { - var clock = instance.container.lookup("clock:main"); - clock.setStartTime(Date.now()); - } -}); -``` - -Added in [PR #10256](https://github.com/emberjs/ember.js/pull/10256). - -For more information, see [the instance initializer deprecation -guide](../instance-initializers). - -### Warnings Added in 1.11 - -#### Binding Style Attributes - - -Content in Handlebars templates is automatically HTML-escaped to help -developers prevent inadvertently introducing cross-site scripting (XSS) -vulnerabilities into their applications. If you want to display trusted -content as HTML, you can use a `SafeString`, a special string that tells Ember -that the content should be displayed without escaping. - -While this works great for HTML, there are some cases where you may bind user -data that the browser interprets as CSS, not HTML. For example, you may bind -the `style` attribute of an element: - -```handlebars -
-``` - -Handlebars only escapes HTML, not CSS, so this may introduce a potential XSS -vulnerability into your application if a malicious user is able to provide data -used in the `myStyle` property. - -Starting in Ember 1.11, you will receive a warning if you attempt to bind the -`style` attribute of an element. Once you have verified that the content being -displayed is trusted and properly escaped, you can disable the warning by -making the content a `SafeString`. For example: - -```js - myStyle: Ember.computed('color', function() { - /* Note: You must implement #escapeCSS. */ - var color = escapeCSS(this.get('color')); - return Ember.String.htmlSafe("color: " + color); - }) -``` - -Make sure you don't put quotes around the sanitized string, `myStyle`, when you -bound it in the template. This would prevent Ember from seeing it as safe. - -You can learn more about `SafeString`s and writing code that prevents XSS -attacks by reading the [Writing -Helpers](http://emberjs.com/guides/templates/writing-helpers/) guide. - -### Deprecations Added in 1.12 - -#### `in` syntax for `{{each}}` - -The `in` syntax is used to name an iterated value with `{{each}}`. Block -params, introduced Ember 1.10, obsoletes the `in` syntax. - -Each helpers should be updated to use block params. For example this helper: - -```handlebars -{{#each foo in bar}} -``` - -Can be converted as follows: - -```handlebars -{{#each bar as |foo|}} -``` -For "itemController" : - -```handlebars -{{#each foo in bar itemController="abc"}} -``` -Can be converted as follows: - -```handlebars -{{#each bar itemController="abc" as |foo|}} -``` - - -#### `as` syntax for `{{with}}` - -Renaming a value using `{{with}}` has been possible using the `as` syntax. Block params, -introduces in Ember 1.10, obsolete the `as` syntax. - -With helpers should be updated to use block params. For example this helper: - -```handlebars -{{#with foo as bar}} -``` - -Can be converted as follows: - -```handlebars -{{#with foo as |bar|}} -``` - - -#### Computed Properties With a Shared Getter And Setter - -Ember.js 1.12 introduces an improved syntax for computed properties with -a setter. Previously, computed properties with a setter implemented that -setter by inspecting the number of arguments passed to the computed -property's descriptor. - -For example, this computed property splits a full name into two -parts when set: - -```js - fullName: Ember.computed("firstName", "lastName", function(key, newName) { - if (arguments.length > 1) { - var parts = newName.split(" "); - this.setProperties({ firstName: parts[0], lastName: parts[1] }); - return newName; - } else { - return this.get("firstName") + " " + this.get("lastName"); - } - }); -``` - -These uses should be converted to use the new discrete getter and setter -syntax introduced in 1.12: - -```js - fullName: Ember.computed("firstName", "lastName", { - get: function() { - return this.get("firstName") + " " + this.get("lastName"); - }, - set: function(key, newName) { - var parts = newName.split(" "); - this.setProperties({ firstName: parts[0], lastName: parts[1] }); - return newName; - } - }); -``` - -For further reading, review the [RFC](https://github.com/emberjs/rfcs/blob/master/text/0011-improved-cp-syntax.md) describing this feature and the [pull request of the initial implementation](https://github.com/emberjs/ember.js/pull/9527). - -### Deprecations Added in 1.13 - -Ember.js 1.13 is the last minor release of Ember 1.x before 2.0. Consequently, -it has a rather large number of notable deprecations. - -#### Ember.create - -`Ember.create` is deprecated in favor for `Object.create`. For more information -regarding `Object.create`, please -[read the MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create). - -Please change this: - -```js -const doug = Ember.create({ - firstName: 'Doug' -}); -``` - -to - -```js -const doug = Object.create({ - firstName: 'Doug' -}); -``` - -#### Ember.keys - -`Ember.keys` is deprecated in favor for `Object.keys`. For more information -regarding `Object.keys`, please -[read the MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys). - -```js -const food = Ember.keys({ - yellow: 'banana', - green: 'pickle' -}); -``` - -to - -```js -const food = Object.keys({ - yellow: 'banana', - green: 'pickle' -}); -``` - -#### Ember.oneWay - -`Ember.oneWay` is deprecated in favor for `Ember.computed.oneWay`. Please -change all instances of `Ember.oneWay` from: - -```js -let User = Ember.Object.extend({ - firstName: null, - nickName: Ember.oneWay('firstName') -}); -``` - -to - -```js -let User = Ember.Object.extend({ - firstName: null, - nickName: Ember.computed.oneWay('firstName') -}); -``` - -#### Ember.View - -Ember 1.x encouraged a Model-View-Controller-Route architecture. Since then, -the web has consolidated around a Model-Component-Route pattern for web -development that Ember 2.0 also embraces. - -Views are removed from the Ember 2.0 API. However a single release is likely -insufficient for large apps to upgrade their entire codebase away from routable -views, and consequently Ember is providing extended support for views via the -[ember-legacy-views](https://github.com/emberjs/ember-legacy-views) addon. -This addon will remain compatible with Ember until v2.4 of the framework -is released. - -Along with the deprecation of `Ember.View`, the `Ember.CoreView` class is also -deprecated. If you were using this class, please migrate to `Ember.Component`. - -##### Migrating away from the view helper - -In most cases Ember views can be replaced with a component. For example -this view and usage: - -```app/templates/show-menu.hbs -{{view.title}} -``` - -```app/views/show-menu.js -import Ember from "ember"; - -// Usage: {{view "show-menu"}} -export default Ember.View.extend({ - templateName: 'some-menu', - title: 'My Menu' -}); -``` - -Can be replaced with this component: - -```app/templates/components/show-menu.hbs -{{title}} -``` - -```app/components/show-menu.js -import Ember from "ember"; - -// Usage: {{show-menu}} -export default Ember.Component.extend({ - title: 'My Menu' -}); -``` - -Note that a component is always its own context in a template. A view's template -may have had access to other variables that were present where it was called, -such as a `controller`. A component template will always be isolated, and -if data is needed it should be passed upon invocation. For example: - -```handlebars -{{show-menu options=controller.menuOptions}} -``` - -##### Differences in yielded blocks - -Some notable differences exist between yielded view blocks and yielded component -blocks. A view could be used this way: - -```app/views/reverse-name.js -import Ember from "ember"; - -export default Ember.View.extend({ - reversedName: Ember.computed('name', function() { - return this.get('name').split("").reverse().join(""); - }) -}); -``` - -```handlebars -{{#view "reverse-name" name=controller.name}} - {{view.reversedName}} -{{/view}} -``` - -Components introduced block params. This concept achieves data passing -without the confusion over what `{{view}}` refers to. For example: - -```app/components/reverse-name.js -import Ember from "ember"; - -export default Ember.Component.extend({ - reversedName: Ember.computed('name', function() { - return this.get('name').split("").reverse().join(""); - }) -}); -``` - -```app/templates/components/reverse-name.hbs -{{yield reversedName}} -``` - -```handlebars -{{#reverse-name name=controller.name as |reversedName|}} - {{reversedName}} -{{/reverse-name}} -``` - -Just as passing values to a component allow access to those values in the -isolated template of that component, yielding block params allow for values -from the component to be passed to the location the component was called at. - -##### Routable Views - -When a template for a given route is rendered, if there is a view with the -same name that view will also be used. For example this view is attached -to the rendered route template: - -```app/router.js -import Ember from "ember"; - -export default Ember.Router.map(function() { - this.route('about'); -}); -``` - -```app/views/about.js -import Ember from "ember"; - -export default Ember.View.extend({ - classNameBindings: ['controller.isActive:active'] -}); -``` - -There are only two reasons a view may be used for a route. - - * To set attribute bindings - * To attach event handlers - -You should migrate away from routed views. For example to attach -bindings an element in the template is sufficient: - -```app/router.js -import Ember from "ember"; - -export default Ember.Router.map(function() { - this.route('about'); -}); -``` - -```app/templates/about.hbs -
- -
-``` - -If attaching events or sharing DOM is necessary, consider a component: - -```app/router.js -import Ember from "ember"; - -export default Ember.Router.map(function() { - this.route('about'); -}); -``` - -```app/templates/about.hbs -{{#active-layout isActive=isActive}} - -{{/active-layout}} -``` - -```app/components/active-layout.js -import Ember from "ember"; - -export default Ember.Component.extend({ - classNameBindings: ['isActive:active'], - click() { - // Handle click - } -}); -``` - -##### view and controller template keywords - -View and controller keywords provided a way to access the view or controller -backing a template, even across scopes that you might expect to be isolated. In -many ways their behavior is emergent, and generally is poorly designed. - -Accessing data via `{{view.someProp}}` or `{{controller.thisThing}}` can -nearly always be replaced by proper use of data passing and block params. See -the guide on [differences in yielded blocks](http://emberjs.com/deprecations/v1.x#toc_differences-in-yielded-blocks) -for a complete example of using block params over the `{{view}}` keyword. - - -##### `view` and `viewClass` arguments to `{{outlet}}` - -Since the View API is deprecated starting in 1.13, providing the `view` or `viewClass` argument to the `{{outlet}}` -helper is likewise deprecated in favor of migrating to component-based approaches, as explained earlier in this -section. - -#### Ember.LinkView - -As a consequence of the deprecation of `Ember.View`, many internal views have -been ported to component. `Ember.LinkView`, the class that backs the -`{{link-to}}` helper, have been ported to `Ember.LinkComponent`. - -Most uses of `Ember.LinkView` can be directly ported to the `Ember.LinkComponent` -class. - -#### Ember.Select - -Using the `Ember.Select` global and its view helper form (`{{view 'select'}}`) -is deprecated. `Ember.Select` in Ember 1.x is implemented in a legacy coding -style that uses patterns such as observers and two-way data binding that -can cause pathological performance problems and provide an experience that -is not consistent with idiomatic Ember 2.0 development. - -Legacy support of `Ember.Select` will be provided via the [ember-legacy-views](https://github.com/emberjs/ember-legacy-views) addon. - -Ember 2.0 provides several new features that make it much more straightforward -to implement <select> tag functionality via the -data-down, actions-up paradigm in one's codebase. -For example, to create a component that displays a prompt and a list of -dropdown options, the following code could be used: - -```app/templates/components/my-select.hbs - -``` - -```app/components/my-select.js -import Ember from "ember"; - -export default Ember.Component.extend({ - content: null, - selectedValue: null, - - didInitAttrs(attrs) { - this._super(...arguments); - var content = this.get('content'); - - if (!content) { - this.set('content', []); - } - }, - - actions: { - change() { - const changeAction = this.get('action'); - const selectedEl = this.$('select')[0]; - const selectedIndex = selectedEl.selectedIndex; - const content = this.get('content'); - const selectedValue = content[selectedIndex]; - - this.set('selectedValue', selectedValue); - changeAction(selectedValue); - } - } -}); -``` - -```app/helpers/is-equal.js -// is-equal helper is necessary to determine which option is currently selected. -import Ember from "ember"; - -export default Ember.Helper.helper(function([leftSide, rightSide]) { - return leftSide === rightSide; -}); -``` - -This component could be used in a template by supplying it an array of strings -as `content` and an action to call when the user makes a selection as `change`: - -```app/templates/application.hbs -The currently selected item: {{mySelectedItem}}. - -{{! myItems is an array of strings: ['first', 'second', 'third',...] }} -{{! This uses the `action` and `mut` helpers to pass in an action that - will update the (outer scope) `mySelectedItem` property with the user's - selection. }} -{{my-select content=myItems action=(action (mut mySelectedItem))}} -``` - -A more complete example of a `select` component that mimics many features of the -deprecated `Ember.Select` is [available in this jsbin](http://emberjs.jsbin.com/fotuqa). - -Here is an [example jsbin showing usage of the select tag directly in a template without a component](http://emberjs.jsbin.com/zezapu). - -There are many [Ember-CLI addons that provide select-like functionality](http://emberobserver.com/categories/select). -[emberx-select](http://emberobserver.com/addons/emberx-select) in particular -aims to provide a select component based on the native html select. Alternative -`select` component implementations can be iterated upon in addons to identify -best practices and perhaps moved into an official Ember 2.x implementation in -the future. - -#### Ember.ContainerView - -`Ember.ContainerView` is deprecated as a consequence of the deprecation of `Ember.View`. - -Legacy support of `Ember.ContainerView` will be provided via the [ember-legacy-views](https://github.com/emberjs/ember-legacy-views) addon. - -##### Migrating away from `Ember.ContainerView` - -In most cases container view can be replaced using the `{{each}}` helper in combination with the `{{component}}` helper. - -```app/components/component-container.js -import Ember from 'ember'; - -export default Ember.Component.extend({ - classNames: ['the-container'], - childComponents: ['a-component', 'b-component'] -}) -``` - -```app/templates/components/component-container.hbs -{{#each childComponents as |childComponent|}} - {{component childComponent}} -{{/each}} -``` - -#### Ember.CollectionView - -`Ember.CollectionView` is deprecated as a consequence of the deprecation of `Ember.View`. - -Legacy support of `Ember.CollectionView` will be provided via the [ember-legacy-views](https://github.com/emberjs/ember-legacy-views) addon. - -##### Migrating away from `Ember.CollectionView` - -In most cases collection view can be replaced using the `{{each}}` helper in combination with the `{{component}}` helper. - -To be able to programmatically decide which component to use for an item, you can use a `Ember.Helper` - -```app/helpers/animal-component.js -import Ember from 'ember'; - -export default Ember.Helper.extend({ - compute: function(params, hash) { - var type = params[0]; - return type + '-component'; - } -}); -``` - -Then if you have these two components: - -```app/templates/components/dog-component.hbs -{{animal.name}} is a dog! -``` - -```app/templates/components/cat-component.hbs -{{animal.name}} is a cat! -``` - -Then you can render your different animals like this: - -```app/controllers/animals.js -import Ember from 'ember'; - -export default Ember.Controller.extend({ - animals: [ - { type: 'cat', name: 'Buttons' }, - { type: 'dog', name: 'Fido'} - ] -}); -``` - -```app/templates/animals.hbs - -``` - -You can [view and manipulate this example on jsbin](http://emberjs.jsbin.com/qegikoliri/1/edit?html,js,output) - -#### Set `positionalParams` as a static property on the class - -Setting `positionalParams` within `.extend` is deprecated. It has to be set as a static property on the class itself (`.reopenClass`). - -Please change this: - -```javascript -import Ember from 'ember'; - -export default Ember.Component.extend({ - positionalParams: [ 'a', 'b' ] -}); -``` - -to this: - -```javascript -import Ember from 'ember'; - -var Thing = Ember.Component.extend(); -Thing.reopenClass({ - positionalParams: [ 'a', 'b' ] -}); - -``` - -#### Ember.ReduceComputed / Ember.ArrayComputed - -These two little monsters served us well for a long time. They provided semantics that allowed to -perform in-place modifications of an existing array instead of replacing the entire array like the -regular `map/reduce` methods in javascript do, which was necessary to avoid expensive repaintings when -rendering lists with the `{{each}}` helper. - -But now that with the new glimmer engine you can generate a entirely new array and let glimmer handle -the diffing for you they've become an unnecessary and overcomplicated abstraction that adds no value -over the native counterparts. - -They will be extracted as an ember addon in case you need to keep using them, but the recommendation now is to -just use the native array methods or those in libraries like Underscore/Lodash. - -#### Ember.ReduceComputedProperty / Ember.ArrayComputedProperty - -In addition to `Ember.ReduceComputed` and `Ember.ArrayComputed` you were able to add a property function call, making use of -the ReduceComputedProperty and ArrayComputedProperty classes. -This usage is also deprecated. -For an example, consider a counter component that displays a total sum of values in an array. -Using `Ember.ReduceComputedProperty` would show the following: - -```js -totalCount: Ember.reduceComputed({ - initialValue = 0; - addedItem(totalValue, newValue) { - return totalValue + newValue; - }, - removedItem(totalValue, newValue) { - return totalValue - newValue; - } -}).property('values') -``` - -Now that these APIs are deprecated, use the native JavaScript reduce along with the [Ember.computed family of functions](http://emberjs.com/api/classes/Ember.computed.html): - -```js -totalCount: Ember.computed('values.[]', function() { - return this.get('values').reduce((previousValue, currentValue) => { - return previousValue + currentValue; - }) -}) -``` - -#### Modifying a Property within `didInsertElement` - -Because of changes in the way Ember renders components in 1.13, setting properties within an overridden `didInsertElement` method -will result in a deprecation warning. - -In many cases you can move your logic earlier in the component lifecycle by implementing the `didReceiveAttrs` hook, one of -[the new hooks introduced in 1.13](http://emberjs.com/blog/2015/06/12/ember-1-13-0-released.html#toc_component-lifecycle-hooks). - -```js - didReceiveAttrs() { - this._super(...arguments); - this.set('myValue', value); - } -``` - -It may even be possible, if your value is constant, to move the change to `init`, where the value can only be set once. - -```js - init() { - this._super(...arguments); - this.set('myValue', myValue); - } -``` - -Don't see a `set` in your `didInsertElement`? It may be in `didUpdate` or `didRender`. Due to a bug, these report the wrong method name. - -Still can't find it? -- One of your computed properties may be calling `set`. -- An observer is being triggered. -- One of your child components may be setting one of its attributes and it is being propagated upward to this component. - -In rare cases, you may be measuring the DOM rendered and want to set an attribute based on that. In this case, it is ok to cause a second render: - -```js - didInsertElement() { - this._super(...arguments); - run.schedule('afterRender', this, this.measureAndSet); - }, - - measureAndSet() { - this.set('height', this.element.children.length * 30); - } -``` - -However, doing so is relatively slow and should be done as a last resort. - -#### beforeObserver - -Before observers are deprecated due to the negative performance implications they have for Ember internals and applications. - -Typically they were used to have access to the old value of a property when it's about to change, but you can get same functionality in an even more efficient way with just a few lines of code: - -```js -function fooObserver(obj){ - var newFoo = obj.get('foo'); - if (obj._oldFoo !== newFoo) { - // do your stuff here - obj._oldFoo = newFoo; - } -} -addObserver(obj, 'foo', fooObserver); -fooObserver(obj); // Optionally call the observer immediately -``` - -The related functions `Ember.addBeforeObserver`, `Ember.removeBeforeObserver`, `Ember.beforeObserversFor`, and `Function#beforeObserver` -are deprecated too. - -#### Ember.immediateObserver - -`Ember.immediateObserver` is deprecated in favor of `Ember.observer`. Please change all instances of `Ember.immediateObserver` from: - -```javascript -Ember.Object.extend({ - valueObserver: Ember.immediateObserver('value', function() { - }) -}); -``` -to - -```javascript -Ember.Object.extend({ - valueObserver: Ember.observer('value', function() { - }) -}); -``` - -#### ArrayController - -Just like `Ember.ObjectController`, `Ember.ArrayController` will be removed in -Ember 2.0 for the same reasons mentioned in [1.11's ObjectController -deprecation](http://emberjs.com/deprecations/v1.x/#toc_objectcontroller). - -To migrate from an explicitly defined array controller, first convert -the class definition to inherit from `Ember.Controller`. For example: - -```js -import Ember from "ember"; - -// Change: -export default Ember.ArrayController.extend({ -// To: -export default Ember.Controller.extend({ - -// ... -``` - -Next update any use of `{{modelPropertyName}}` in templates with `{{model.modelPropertyName}}`. -You should also review any computed property dependent keys, observer keys, and `get` and `set` -statements on the route and controller. An example of how to make this migration can -be found [in this PR to the Ghost project](https://github.com/TryGhost/Ghost/pull/5468). - -Opposite to [1.11's ObjectController deprecation](http://emberjs.com/deprecations/v1.x/#toc_objectcontroller), -if a controller is not explicitly defined, but instead is being auto-generated -by the framework, it will **not** throw a deprecation message even if the -proxying behavior is being used. - -Added in [PR #11476](https://github.com/emberjs/ember.js/pull/11476). - -#### SortableMixin - -Along with `Ember.ArrayController`, `Ember.SortableMixin` will be removed in Ember 2.0. - -You can migrate away from using `Ember.SortableMixin` by using `Ember.computed.sort`. Using this example: - -```js -const SongsController = Ember.ArrayController.extend(Ember.SortableMixin, { - model: null, - sortProperties: ['trackNumber'], - sortAscending: false -}); - -let songsController = SongsController.create({ songs: songList }); -``` - -You can transition to using `Ember.computed.sort` like this: - -```js -const SongsController = Ember.Controller.extend({ - model: null, - sortedSongs: Ember.computed.sort('model', 'songSorting'), - songSorting: ['trackNumber:desc'] -}); - -let songsController = SongsController.create({ songs: songList }); -``` - -You can [read more about `Ember.computed.sort` in the Ember API documentation](http://emberjs.com/api/classes/Ember.computed.html#method_sort) - -Legacy support of `Ember.SortableMixin` will be provided via the [ember-legacy-controllers](https://github.com/emberjs/ember-legacy-controllers) addon. - -#### RenderBuffer - -With the change to the rendering process in Glimmer, the RenderBuffer is no longer used by Ember -and will be removed. The class was originally private, and any reference to it should be removed. - -#### Using `@guid` and `@item` as key in `{{each}}` - -As of 1.13.2 you should not use `key='@guid'` or `key='@item'` in the `{{each}}` helper. It is -[documented in 1.13](http://guides.emberjs.com/v1.13.0/templates/displaying-a-list-of-items/#toc_specifying-keys) -that you can use these special values to uniquely identify each array entry so that the view code could -more efficiently re-render the display of the list. - -This process was simplified as part of a [bugfix](https://github.com/emberjs/ember.js/pull/11461), -where the key now implicitly defaults to `@identity`, which will pick either a guid or an item identifier based on type -of each array entry. Therefore, providing the key attribute is no longer required for re-render optimizations. - -Applications should replace instances of: - -```handlebars -{{#each people key='@guid' as |person|}} -... -{{/each}} -``` - -and - -```handlebars -{{#each people key='@item' as |person|}} -... -{{/each}} -``` - -with - -```handlebars -{{#each people as |person|}} -... -{{/each}} -``` - -#### Controller.needs - -`needs` for controllers will be removed in Ember 2.0. You can migrate away from this using `Ember.inject.controller` - -Lets say you have a `post` controller like this: - -```javascript -import Ember from 'ember'; - -export default Ember.Controller.extend({ - needs: ['comments'], - newComments: Ember.computed.alias('controllers.comments.newest') -}); -``` - -You can upgrade to `Ember.inject.controller` like this: - -```javascript -import Ember from 'ember'; - -export default Ember.Controller.extend({ - comments: Ember.inject.controller(), - newComments: Ember.computed.alias('comments.newest') -}); -``` - -You can [read more about `Ember.inject.controller` in the Ember API documentation](http://emberjs.com/api/classes/Ember.inject.html#method_controller) - -#### Block and multi-argument unbound helper - -The unbound helper is mostly a legacy API in Ember, although it is not being -removed in 2.0. It was almost exclusively used to manage performance issues -which are well addressed in Ember 1.13's new rendering engine. - -The first form being deprecated is the block form of unbound. For example: - -```handlebars -{{#unbound if someState}} - Show this -{{/unbound}} -``` - -Instead, replace this form with a nested helper: - -```handlebars -{{#if (unbound someState)}} - Show this -{{/if}} -``` - -The second form being deprecated is the non-nested helper lookup. For example: - -```handlebars -{{unbound some-custom-helper withArg anotherArg}} -``` - -Replace this form with nested helper call: - -```handlebars -{{unbound (some-custom-helper withArg anotherArg)}} -``` - -Or make all inputs to the helper unbound: - -```handlebars -{{some-custom-helper (unbound withArg) (unbound anotherArg)}} -``` - -#### Ember Freezable - -The Freezable Mixin has been deprecated because the spec has been added to -the javascript core. - -```javascript -Contact = Ember.Object.extend(Ember.Freezable, { - firstName: null, - lastName: null, - - // swaps the names - swapNames: function() { - if (this.get('isFrozen')) throw Ember.FROZEN_ERROR; - var tmp = this.get('firstName'); - this.set('firstName', this.get('lastName')); - this.set('lastName', tmp); - return this; - } - -}); - -c = Contact.create({ firstName: "John", lastName: "Doe" }); -c.swapNames(); // returns c -c.freeze(); -c.swapNames(); // EXCEPTION -``` - -Replace code above with this: - -```javascript -Contact = Ember.Object.extend({ - firstName: null, - lastName: null, - - // swaps the names - swapNames: function() { - if (Object.isFrozen(this)) throw Ember.FROZEN_ERROR; - var tmp = this.get('firstName'); - this.set('firstName', this.get('lastName')); - this.set('lastName', tmp); - return this; - } - -}); - -c = Contact.create({ firstName: "John", lastName: "Doe" }); -c.swapNames(); // returns c -Object.freeze(c); -c.swapNames(); // EXCEPTION -``` - -#### Ember.EnumerableUtils - -`EnumerableUtils` has been deprecated in favor of native implementations. You can consult the -[JavaScript Array documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) -to find suitable replacements for `EnumerableUtils` functionality. -If the native JavaScript array object does not provide a suitable equivalent for your needs, you might also want to checkout -third party utility libraries like [lodash](https://lodash.com/), or [underscore](underscorejs.org/). - -#### Copyable.frozenCopy - -Just as the `Freezable` mixin is deprecated in favor of functionality in -core JavaScript, the `frozenCopy` method of the Copyable mixin is also -deprecated in favor of [`Object.freeze()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze). - -Replace the following code: - -```javascript -const Obj = Ember.Object.extend(Freezable, Copyable, { - copy() { - return Obj.create(); - } -}); - -const frozenCopy = Obj.create().frozenCopy(); -frozenCopy.isFrozen(); // => true -frozenCopy.set('foo', 'baz'); // => throws TypeError -``` - -with: - -```javascript -const a = Ember.Object.create(); -Object.isFrozen(a); // => false -Object.freeze(a); -Object.isFrozen(a); // => true -a.set('foo', 'baz'); // => throws TypeError -``` -#### Using `/` for namespace in the `{{render}}` helper - -When using the render helper, its possible to specify a context within a nested directory structure. Prior to 1.13, it -was acceptable to separate nested directories using slashes `/`, but this is now deprecated, as Ember has -settled on using dot notation for namespacing. - -For example, a developer might have a controller at `app/controllers/blog/posts.js` and is using the render helper to -render that controller context within another template. - -Instead of using `{{render 'blog/posts'}}`, use `{{render 'blog.posts'}}`. That will render the template associated with -`app/controllers/blog/posts.js` in your directory structure. - -#### Non-Standard Ways of Calling `Ember.set` and `Ember.get` - -Ember is deprecating calls to `get` and `set` made in non-standard ways. Below are examples -of the calls that are now deprecated: - -```javascript -// referencing properties with globals -Ember.set(null, 'App.foo', bar); -Ember.set('App.foo', bar); -Ember.get(null, 'App.foo'); -Ember.get('App.foo'); - -// referencing properties with 'this' -Ember.set(obj, 'this.foo', bar); -Ember.get(obj, 'this.foo'); - -// providing a null context -Ember.set(null, 'foo', bar); -Ember.get(null, 'foo'); - -// providing a non-string property -Ember.set(obj, 42, bar); -Ember.get(obj, 42); -``` - -#### Reversed Ember.observer Arguments - -A little known feature of the observer function allowed for the arguments to be -listed in the opposite order, with function first: - -```javascript -Ember.observer(function() { - // React to observer firing here -}, 'property1', 'property2') -``` - -This syntax was deprecated in Ember 1.13.5. The above code sample should be -replaced with the standard syntax that lists the observed properties, then -the function as the last argument: - -```javascript -Ember.observer('property1', 'property2', function() { - // React to observer firing here -}) -``` - -#### Ember CreateWithMixins - -`Ember.Object.createWithMixins` method has been deprecated. Instead call `Ember.Object.create` or `Ember.Object.extend`. - -```javascript -var obj = Ember.Object.createWithMixins({ - -}); -``` - -Replace with code above with: - -```javascript -var obj = Ember.Object.extend({ - -}).create(); -``` - -#### bind-attr - -Ember 1.11 introduced new syntax for using dynamic content in attributes. - -In 1.10 your only option was to use the `bind-attr` helper: - -```handlebars -
-``` - -Ember 1.11 made it possible to intuitively represent dynamic content in attributes as you would expect: - -```handlebars -
-``` - -This makes it possible to express a number of concepts directly in the template that previously were awkward to represent and required computer properties, and could even require `itemController`. - -##### Dasherized boolean values - -Ember 1.11's attribute binding syntax no longer supports dasherizing for boolean values. For example: - -```app/components/user-profile.js -export default Ember.Component.extend({ - isActiveUser: true -}); -``` - -```app/templates/components/user-profile.hbs -
-
-``` - -Should be replaced with: - -```app/templates/components/user-profile.hbs -
-
-``` - -##### Legacy `bind-attr` - -Ember 1.13 deprecated `bind-attr` in favor of the new syntax. - -To aid in the migration, you can use the [legacy-bind-attr plugin](https://github.com/emberjs/legacy-bind-attr) to restore this behavior in Ember 2.0 and silence the deprecation warning. - -#### Using `this.get('template')` - -Prior to 1.13, developers had to check for the existance of the internal `template` property to determine the existance of a yielded block. -This is being deprecated in favor of using the new [`hasBlock`](http://emberjs.com/api/classes/Ember.Component.html#property_hasBlock) -property within your templates. - -##### Determining if a block has been provided from JavaScript - -Currently the `hasBlock` property is not made available from the JavaScript component object, -so there is no clean alternative for checking whether a block has been passed. -See the [JavaScript `hasBlock` RFC](https://github.com/emberjs/rfcs/pull/102) for discussion on making this information -available in the future, as well as possible workarounds. - -#### Ember.computed.any - -`Ember.computed.any` is deprecated in favor of `Ember.computed.or`. This change is required because the computed value is the first value ( like || ) rather than a boolean value ( like Array.prototype.any ). For example: - -```javascript -let Hamster = Ember.Object.extend({ - hasClothes: Ember.computed.any('hat', 'shirt') -}); -``` -The above code will be changed to - -```javascript -let Hamster = Ember.Object.extend({ - hasClothes: Ember.computed.or('hat', 'shirt') -}); -``` - -#### View and Controller options on the `{{each}}` helper - -The options `itemView`, `itemViewClass`, `tagName`, `emptyView`, -`emptyViewClass` and `itemController` on the `{{each}}` helper have been deprecated. - -These options were added when controllers were more prominent, and the -component story was less fully fleshed out. In Ember 1.13+, using these options -triggers a less performant compatibility mode. - -The usage of all the above mentioned options should be replaced with components. - -##### An example - -```handlebars -{{each view.comments itemController="comment" - itemView="commentView" - emptyView="noCommentsView" - tagName="ul"}} -``` - -Can be replaced with: - -```handlebars - -``` - -##### Breaking the example down - -The `comment` controller and `commentView` view have been refactored into the -`{{post-comment}}` component. - -The `noCommentsView` has been refactored in to the `{{no-comments}}` component. - -Instead of the `itemController="comment"` and `itemView="commentView"` we use -the newly created `{{post-comment}}` component. - -Instead of the `emptyView="noCommentsView"` we use the `{{no-comments}}` -component. - -We replaced `tagName="ul"` part by just surrounding the `{{each}}` block with -`