diff --git a/packages/@ember/-internals/metal/lib/computed.ts b/packages/@ember/-internals/metal/lib/computed.ts
index 750c45d57c3..d2b45df16fe 100644
--- a/packages/@ember/-internals/metal/lib/computed.ts
+++ b/packages/@ember/-internals/metal/lib/computed.ts
@@ -47,50 +47,140 @@ const DEEP_EACH_REGEX = /\.@each\.[^.]+\./;
function noop(): void {}
/**
- A computed property transforms an object literal with object's accessor function(s) into a property.
+ `@computed` is a decorator that turns a JavaScript getter and setter into a
+ computed property, which is a _cached, trackable value_. By default the getter
+ will only be called once and the result will be cached. You can specify
+ various properties that your computed property depends on. This will force the
+ cached result to be cleared if the dependencies are modified, and lazily recomputed the next time something asks for it.
+
+ In the following example we decorate a getter - `fullName` - by calling
+ `computed` with the property dependencies (`firstName` and `lastName`) as
+ arguments. The `fullName` getter will be called once (regardless of how many
+ times it is accessed) as long as its dependencies do not change. Once
+ `firstName` or `lastName` are updated any future calls to `fullName` will
+ incorporate the new values, and any watchers of the value such as templates
+ will be updated:
- By default the function backing the computed property will only be called
- once and the result will be cached. You can specify various properties
- that your computed property depends on. This will force the cached
- result to be recomputed if the dependencies are modified.
+ ```javascript
+ import { computed, set } from '@ember/object';
+
+ class Person {
+ constructor(firstName, lastName) {
+ set(this, 'firstName', firstName);
+ set(this, 'lastName', lastName);
+ }
+
+ @computed('firstName', 'lastName')
+ get fullName() {
+ return `${this.firstName} ${this.lastName}`;
+ }
+ });
+
+ let tom = new Person('Tom', 'Dale');
- In the following example we declare a computed property - `fullName` - by calling
- `computed` with property dependencies (`firstName` and `lastName`) as leading arguments and getter accessor function. The `fullName` getter function
- will be called once (regardless of how many times it is accessed) as long
- as its dependencies have not changed. Once `firstName` or `lastName` are updated
- any future calls (or anything bound) to `fullName` will incorporate the new
- values.
+ tom.fullName; // 'Tom Dale'
+ ```
+
+ You can also provide a setter, which will be used when updating the computed
+ property. Ember's `set` function must be used to update the property
+ since it will also notify observers of the property:
```javascript
- import EmberObject, { computed } from '@ember/object';
+ import { computed, set } from '@ember/object';
- let Person = EmberObject.extend({
- // these will be supplied by `create`
- firstName: null,
- lastName: null,
+ class Person {
+ constructor(firstName, lastName) {
+ set(this, 'firstName', firstName);
+ set(this, 'lastName', lastName);
+ }
- fullName: computed('firstName', 'lastName', function() {
- let firstName = this.get('firstName'),
- lastName = this.get('lastName');
+ @computed('firstName', 'lastName')
+ get fullName() {
+ return `${this.firstName} ${this.lastName}`;
+ }
- return `${firstName} ${lastName}`;
- })
+ set fullName(value) {
+ let [firstName, lastName] = value.split(' ');
+
+ set(this, 'firstName', firstName);
+ set(this, 'lastName', lastName);
+ }
});
- let tom = Person.create({
- firstName: 'Tom',
- lastName: 'Dale'
+ let person = new Person();
+
+ set(person, 'fullName', 'Peter Wagenet');
+ person.firstName; // 'Peter'
+ person.lastName; // 'Wagenet'
+ ```
+
+ You can also pass a getter function or object with `get` and `set` functions
+ as the last argument to the computed decorator. This allows you to define
+ computed property _macros_:
+
+ ```js
+ import { computed } from '@ember/object';
+
+ function join(...keys) {
+ return computed(...keys, function() {
+ return keys.map(key => this[key]).join(' ');
+ });
+ }
+
+ class Person {
+ @join('firstName', 'lastName')
+ fullName;
+ }
+ ```
+
+ Note that when defined this way, getters and setters receive the _key_ of the
+ property they are decorating as the first argument. Setters receive the value
+ they are setting to as the second argument instead. Additionally, setters must
+ _return_ the value that should be cached:
+
+ ```javascript
+ import { computed, set } from '@ember/object';
+
+ function fullNameMacro(firstNameKey, lastNameKey) {
+ @computed(firstNameKey, lastNameKey, {
+ get() {
+ return `${this[firstNameKey]} ${this[lastNameKey]}`;
+ }
+
+ set(key, value) {
+ let [firstName, lastName] = value.split(' ');
+
+ set(this, firstNameKey, firstName);
+ set(this, lastNameKey, lastName);
+
+ return value;
+ }
+ });
+ }
+
+ class Person {
+ constructor(firstName, lastName) {
+ set(this, 'firstName', firstName);
+ set(this, 'lastName', lastName);
+ }
+
+ @fullNameMacro fullName;
});
- tom.get('fullName') // 'Tom Dale'
+ let person = new Person();
+
+ set(person, 'fullName', 'Peter Wagenet');
+ person.firstName; // 'Peter'
+ person.lastName; // 'Wagenet'
```
- You can also define what Ember should do when setting a computed property by providing additional function (`set`) in hash argument.
- If you try to set a computed property, it will try to invoke setter accessor function with the key and
- value you want to set it to as arguments.
+ Computed properties can also be used in classic classes. To do this, we
+ provide the getter and setter as the last argument like we would for a macro,
+ and we assign it to a property on the class definition. This is an _anonymous_
+ computed macro:
```javascript
- import EmberObject, { computed } from '@ember/object';
+ import EmberObject, { computed, set } from '@ember/object';
let Person = EmberObject.extend({
// these will be supplied by `create`
@@ -98,57 +188,54 @@ function noop(): void {}
lastName: null,
fullName: computed('firstName', 'lastName', {
- get(key) {
- let firstName = this.get('firstName'),
- lastName = this.get('lastName');
+ get() {
+ return `${this.firstName} ${this.lastName}`;
+ }
- return firstName + ' ' + lastName;
- },
set(key, value) {
let [firstName, lastName] = value.split(' ');
- this.set('firstName', firstName);
- this.set('lastName', lastName);
+ set(this, 'firstName', firstName);
+ set(this, 'lastName', lastName);
return value;
}
})
});
- let person = Person.create();
+ let tom = Person.create({
+ firstName: 'Tom',
+ lastName: 'Dale'
+ });
- person.set('fullName', 'Peter Wagenet');
- person.get('firstName'); // 'Peter'
- person.get('lastName'); // 'Wagenet'
+ tom.get('fullName') // 'Tom Dale'
```
- You can overwrite computed property with normal property (no longer computed), that won't change if dependencies change, if you set computed property and it won't have setter accessor function defined.
-
- You can also mark computed property as `.readOnly()` and block all attempts to set it.
+ You can overwrite computed property without setters with a normal property (no
+ longer computed) that won't change if dependencies change. You can also mark
+ computed property as `.readOnly()` and block all attempts to set it.
```javascript
- import EmberObject, { computed } from '@ember/object';
-
- let Person = EmberObject.extend({
- // these will be supplied by `create`
- firstName: null,
- lastName: null,
+ import { computed, set } from '@ember/object';
- fullName: computed('firstName', 'lastName', {
- get(key) {
- let firstName = this.get('firstName');
- let lastName = this.get('lastName');
+ class Person {
+ constructor(firstName, lastName) {
+ set(this, 'firstName', firstName);
+ set(this, 'lastName', lastName);
+ }
- return firstName + ' ' + lastName;
- }
- }).readOnly()
+ @computed('firstName', 'lastName').readOnly()
+ get fullName() {
+ return `${this.firstName} ${this.lastName}`;
+ }
});
- let person = Person.create();
+ let person = new Person();
person.set('fullName', 'Peter Wagenet'); // Uncaught Error: Cannot set read-only property "fullName" on object: <(...):emberXXX>
```
Additional resources:
+ - [Decorators RFC](https://github.com/emberjs/rfcs/blob/master/text/0408-decorators.md)
- [New CP syntax RFC](https://github.com/emberjs/rfcs/blob/master/text/0011-improved-cp-syntax.md)
- [New computed syntax explained in "Ember 1.12 released" ](https://emberjs.com/blog/2015/05/13/ember-1-12-released.html#toc_new-computed-syntax)
diff --git a/packages/@ember/controller/index.js b/packages/@ember/controller/index.js
index a5e3f602888..644b9b35819 100644
--- a/packages/@ember/controller/index.js
+++ b/packages/@ember/controller/index.js
@@ -25,21 +25,33 @@ const Controller = EmberObject.extend(ControllerMixin);
inject as controller
} from '@ember/controller';
+ export default class PostController extends Controller {
+ @controller posts;
+ }
+ ```
+
+ Classic Class Example:
+
+ ```app/controllers/post.js
+ import Controller, {
+ inject as controller
+ } from '@ember/controller';
+
export default Controller.extend({
posts: controller()
});
```
This example will create a `posts` property on the `post` controller that
- looks up the `posts` controller in the container, making it easy to
- reference other controllers.
+ looks up the `posts` controller in the container, making it easy to reference
+ other controllers.
@method inject
@static
@for @ember/controller
@since 1.10.0
- @param {String} name (optional) name of the controller to inject, defaults
- to the property's name
+ @param {String} name (optional) name of the controller to inject, defaults to
+ the property's name
@return {ComputedDecorator} injection decorator instance
@public
*/
diff --git a/packages/@ember/object/index.js b/packages/@ember/object/index.js
index e28e8c452aa..f6c720ea8ed 100644
--- a/packages/@ember/object/index.js
+++ b/packages/@ember/object/index.js
@@ -3,31 +3,109 @@ import { assert } from '@ember/debug';
import { assign } from '@ember/polyfills';
/**
- Decorator that turns the target function into an Action
- Adds an `actions` object to the target object and creates a passthrough
- function that calls the original. This means the function still exists
- on the original object, and can be used directly.
+ Decorator that turns the target function into an Action which can be accessed
+ directly by reference.
```js
- export default class ActionDemoComponent extends Component {
+ import Component from '@ember/component';
+ import { action, set } from '@ember/object';
+
+ export default class Tooltip extends Component {
@action
- foo() {
- // do something
+ toggleShowing() {
+ set(this, 'isShowing', !this.isShowing);
}
}
```
```hbs
-
+
+
+ {{#if isShowing}}
+
+ I'm a tooltip!
+
+ {{/if}}
+ ```
+
+ Decorated actions also interop with the string style template actions:
+
+ ```hbs
+
+
+
+ {{#if isShowing}}
+
+ I'm a tooltip!
+
+ {{/if}}
```
It also binds the function directly to the instance, so it can be used in any
- context:
+ context and will correctly refer to the class it came from:
+
+ ```hbs
+
+
+
+ {{#if isShowing}}
+
+ I'm a tooltip!
+
+ {{/if}}
+ ```
+
+ This can also be used in JavaScript code directly:
+
+ ```js
+ import Component from '@ember/component';
+ import { action, set } from '@ember/object';
+
+ export default class Tooltip extends Component {
+ constructor() {
+ super(...arguments);
+
+ // this.toggleShowing is still bound correctly when added to
+ // the event listener
+ document.addEventListener('click', this.toggleShowing);
+ }
+
+ @action
+ toggleShowing() {
+ set(this, 'isShowing', !this.isShowing);
+ }
+ }
+ ```
+
+ This is considered best practice, since it means that methods will be bound
+ correctly no matter where they are used. By contrast, the `{{action}}` helper
+ and modifier can also be used to bind context, but it will be required for
+ every usage of the method:
```hbs
-
+
+
+ {{#if isShowing}}
+
+ I'm a tooltip!
+
+ {{/if}}
```
+
+ They also do not have equivalents in JavaScript directly, so they cannot be
+ used for other situations where binding would be useful.
+
@method action
@category EMBER_NATIVE_DECORATOR_SUPPORT
@for @ember/object
diff --git a/packages/@ember/object/lib/computed/computed_macros.js b/packages/@ember/object/lib/computed/computed_macros.js
index f904bfa07fa..d0de2a2ac2d 100644
--- a/packages/@ember/object/lib/computed/computed_macros.js
+++ b/packages/@ember/object/lib/computed/computed_macros.js
@@ -55,14 +55,37 @@ function generateComputedWithPredicate(name, predicate) {
}
/**
- A computed property that returns true if the value of the dependent
+ A computed property macro that returns true if the value of the dependent
property is null, an empty string, empty array, or empty function.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { empty } from '@ember/object/computed';
+
+ class ToDoList {
+ constructor(todos) {
+ set(this, 'todos', todos);
+ }
+
+ @empty('todos') isDone;
+ }
+
+ let todoList = new ToDoList(
+ ['Unit Test', 'Documentation', 'Release']
+ );
+
+ todoList.isDone; // false
+ set(todoList, 'todos', []);
+ todoList.isDone; // true
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { empty } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let ToDoList = EmberObject.extend({
isDone: empty('todos')
@@ -72,9 +95,9 @@ function generateComputedWithPredicate(name, predicate) {
todos: ['Unit Test', 'Documentation', 'Release']
});
- todoList.get('isDone'); // false
- todoList.get('todos').clear();
- todoList.get('isDone'); // true
+ todoList.isDone; // false
+ set(todoList, 'todos', []);
+ todoList.isDone; // true
```
@since 1.6.0
@@ -82,9 +105,9 @@ function generateComputedWithPredicate(name, predicate) {
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which returns true if
- the value of the dependent property is null, an empty string, empty array,
- or empty function and false if the underlying value is not empty.
+ @return {ComputedProperty} computed property which returns true if the value
+ of the dependent property is null, an empty string, empty array, or empty
+ function and false if the underlying value is not empty.
@public
*/
@@ -95,32 +118,57 @@ export function empty(dependentKey) {
}
/**
- A computed property that returns true if the value of the dependent
- property is NOT null, an empty string, empty array, or empty function.
+ A computed property that returns true if the value of the dependent property
+ is NOT null, an empty string, empty array, or empty function.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { notEmpty } from '@ember/object/computed';
+
+ class Hamster {
+ constructor(backpack) {
+ set(this, 'backpack', backpack);
+ }
+
+ @notEmpty('backpack') hasStuff
+ }
+
+ let hamster = new Hamster(
+ ['Food', 'Sleeping Bag', 'Tent']
+ );
+
+ hamster.hasStuff; // true
+ set(hamster, 'backpack', []);
+ hamster.hasStuff; // false
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { notEmpty } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
hasStuff: notEmpty('backpack')
});
- let hamster = Hamster.create({ backpack: ['Food', 'Sleeping Bag', 'Tent'] });
+ let hamster = Hamster.create({
+ backpack: ['Food', 'Sleeping Bag', 'Tent']
+ });
- hamster.get('hasStuff'); // true
- hamster.get('backpack').clear(); // []
- hamster.get('hasStuff'); // false
+ hamster.hasStuff; // true
+ set(hamster, 'backpack', []);
+ hamster.hasStuff; // false
```
@method notEmpty
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which returns true if
- original value for property is not empty.
+ @return {ComputedProperty} computed property which returns true if original
+ value for property is not empty.
@public
*/
export function notEmpty(dependentKey) {
@@ -130,15 +178,34 @@ export function notEmpty(dependentKey) {
}
/**
- A computed property that returns true if the value of the dependent
- property is null or undefined. This avoids errors from JSLint complaining
- about use of ==, which can be technically confusing.
+ A computed property that returns true if the value of the dependent property
+ is null or undefined. This avoids errors from JSLint complaining about use of
+ ==, which can be technically confusing.
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { none } from '@ember/object/computed';
+
+ class Hamster {
+ @none('food') isHungry;
+ }
- Example
+ let hamster = new Hamster();
+
+ hamster.isHungry; // true
+
+ set(hamster, 'food', 'Banana');
+ hamster.isHungry; // false
+
+ set(hamster, 'food', null);
+ hamster.isHungry; // true
+ ```
+
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { none } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
isHungry: none('food')
@@ -146,19 +213,21 @@ export function notEmpty(dependentKey) {
let hamster = Hamster.create();
- hamster.get('isHungry'); // true
- hamster.set('food', 'Banana');
- hamster.get('isHungry'); // false
- hamster.set('food', null);
- hamster.get('isHungry'); // true
+ hamster.isHungry; // true
+
+ set(hamster, 'food', 'Banana');
+ hamster.isHungry; // false
+
+ set(hamster, 'food', null);
+ hamster.isHungry; // true
```
@method none
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which
- returns true if original value for property is null or undefined.
+ @return {ComputedProperty} computed property which returns true if original
+ value for property is null or undefined.
@public
*/
export function none(dependentKey) {
@@ -168,32 +237,53 @@ export function none(dependentKey) {
}
/**
- A computed property that returns the inverse boolean value
- of the original value for the dependent property.
+ A computed property that returns the inverse boolean value of the original
+ value for the dependent property.
+
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { not } from '@ember/object/computed';
+
+ class User {
+ loggedIn = false;
+
+ @not('loggedIn') isAnonymous;
+ }
+
+ let user = new User();
+
+ user.isAnonymous; // true
+ set(user, 'loggedIn', true);
+ user.isAnonymous; // false
+ ```
- Example
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { not } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let User = EmberObject.extend({
+ loggedIn: false,
+
isAnonymous: not('loggedIn')
});
- let user = User.create({loggedIn: false});
+ let user = User.create();
- user.get('isAnonymous'); // true
- user.set('loggedIn', true);
- user.get('isAnonymous'); // false
+ user.isAnonymous; // true
+ set(user, 'loggedIn', true);
+ user.isAnonymous; // false
```
@method not
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which returns
- inverse of the original value for property
+ @return {ComputedProperty} computed property which returns inverse of the
+ original value for property
@public
*/
export function not(dependentKey) {
@@ -203,12 +293,40 @@ export function not(dependentKey) {
}
/**
- A computed property that converts the provided dependent property
- into a boolean value.
+ A computed property that converts the provided dependent property into a
+ boolean value.
+
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { bool } from '@ember/object/computed';
+
+
+ class Hamster {
+ @bool('numBananas') hasBananas
+ }
+
+ let hamster = new Hamster();
+
+ hamster.hasBananas; // false
+
+ set(hamster, 'numBananas', 0);
+ hamster.hasBananas; // false
+
+ set(hamster, 'numBananas', 1);
+ hamster.hasBananas; // true
+
+ set(hamster, 'numBananas', null);
+ hamster.hasBananas; // false
+ ```
+
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { bool } from '@ember/object/computed';
- import EmberObject from '@ember/object';
+
let Hamster = EmberObject.extend({
hasBananas: bool('numBananas')
@@ -216,21 +334,24 @@ export function not(dependentKey) {
let hamster = Hamster.create();
- hamster.get('hasBananas'); // false
- hamster.set('numBananas', 0);
- hamster.get('hasBananas'); // false
- hamster.set('numBananas', 1);
- hamster.get('hasBananas'); // true
- hamster.set('numBananas', null);
- hamster.get('hasBananas'); // false
+ hamster.hasBananas; // false
+
+ set(hamster, 'numBananas', 0);
+ hamster.hasBananas; // false
+
+ set(hamster, 'numBananas', 1);
+ hamster.hasBananas; // true
+
+ set(hamster, 'numBananas', null);
+ hamster.hasBananas; // false
```
@method bool
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which converts
- to boolean the original value for property
+ @return {ComputedProperty} computed property which converts to boolean the
+ original value for property
@public
*/
export function bool(dependentKey) {
@@ -240,27 +361,50 @@ export function bool(dependentKey) {
}
/**
- A computed property which matches the original value for the
- dependent property against a given RegExp, returning `true`
- if the value matches the RegExp and `false` if it does not.
+ A computed property which matches the original value for the dependent
+ property against a given RegExp, returning `true` if the value matches the
+ RegExp and `false` if it does not.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { match } from '@ember/object/computed';
+
+ class User {
+ @match('email', /^.+@.+\..+$/) hasValidEmail;
+ }
+
+ let user = new User();
+
+ user.hasValidEmail; // false
+
+ set(user, 'email', '');
+ user.hasValidEmail; // false
+
+ set(user, 'email', 'ember_hamster@example.com');
+ user.hasValidEmail; // true
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { match } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let User = EmberObject.extend({
hasValidEmail: match('email', /^.+@.+\..+$/)
});
- let user = User.create({loggedIn: false});
+ let user = User.create();
+
+ user.hasValidEmail; // false
- user.get('hasValidEmail'); // false
- user.set('email', '');
- user.get('hasValidEmail'); // false
- user.set('email', 'ember_hamster@example.com');
- user.get('hasValidEmail'); // true
+ set(user, 'email', '');
+ user.hasValidEmail; // false
+
+ set(user, 'email', 'ember_hamster@example.com');
+ user.hasValidEmail; // true
```
@method match
@@ -268,8 +412,8 @@ export function bool(dependentKey) {
@for @ember/object/computed
@param {String} dependentKey
@param {RegExp} regexp
- @return {ComputedProperty} computed property which match
- the original value for property against a given RegExp
+ @return {ComputedProperty} computed property which match the original value
+ for property against a given RegExp
@public
*/
export function match(dependentKey, regexp) {
@@ -280,14 +424,35 @@ export function match(dependentKey, regexp) {
}
/**
- A computed property that returns true if the provided dependent property
- is equal to the given value.
+ A computed property that returns true if the provided dependent property is
+ equal to the given value.
+
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { equal } from '@ember/object/computed';
+
+ class Hamster {
+ @equal('percentCarrotsEaten', 100) satisfied;
+ }
+
+ let hamster = new Hamster();
+
+ hamster.satisfied; // false
+
+ set(hamster, 'percentCarrotsEaten', 100);
+ hamster.satisfied; // true
+
+ set(hamster, 'percentCarrotsEaten', 50);
+ hamster.satisfied; // false
+ ```
- Example
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { equal } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
satisfied: equal('percentCarrotsEaten', 100)
@@ -295,11 +460,13 @@ export function match(dependentKey, regexp) {
let hamster = Hamster.create();
- hamster.get('satisfied'); // false
- hamster.set('percentCarrotsEaten', 100);
- hamster.get('satisfied'); // true
- hamster.set('percentCarrotsEaten', 50);
- hamster.get('satisfied'); // false
+ hamster.satisfied; // false
+
+ set(hamster, 'percentCarrotsEaten', 100);
+ hamster.satisfied; // true
+
+ set(hamster, 'percentCarrotsEaten', 50);
+ hamster.satisfied; // false
```
@method equal
@@ -307,8 +474,8 @@ export function match(dependentKey, regexp) {
@for @ember/object/computed
@param {String} dependentKey
@param {String|Number|Object} value
- @return {ComputedProperty} computed property which returns true if
- the original value for property is equal to the given value.
+ @return {ComputedProperty} computed property which returns true if the
+ original value for property is equal to the given value.
@public
*/
export function equal(dependentKey, value) {
@@ -318,14 +485,35 @@ export function equal(dependentKey, value) {
}
/**
- A computed property that returns true if the provided dependent property
- is greater than the provided value.
+ A computed property that returns true if the provided dependent property is
+ greater than the provided value.
+
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { gt } from '@ember/object/computed';
+
+ class Hamster {
+ @gt('numBananas', 10) hasTooManyBananas;
+ }
+
+ let hamster = new Hamster();
- Example
+ hamster.hasTooManyBananas; // false
+
+ set(hamster, 'numBananas', 3);
+ hamster.hasTooManyBananas; // false
+
+ set(hamster, 'numBananas', 11);
+ hamster.hasTooManyBananas; // true
+ ```
+
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { gt } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
hasTooManyBananas: gt('numBananas', 10)
@@ -333,11 +521,13 @@ export function equal(dependentKey, value) {
let hamster = Hamster.create();
- hamster.get('hasTooManyBananas'); // false
- hamster.set('numBananas', 3);
- hamster.get('hasTooManyBananas'); // false
- hamster.set('numBananas', 11);
- hamster.get('hasTooManyBananas'); // true
+ hamster.hasTooManyBananas; // false
+
+ set(hamster, 'numBananas', 3);
+ hamster.hasTooManyBananas; // false
+
+ set(hamster, 'numBananas', 11);
+ hamster.hasTooManyBananas; // true
```
@method gt
@@ -345,8 +535,8 @@ export function equal(dependentKey, value) {
@for @ember/object/computed
@param {String} dependentKey
@param {Number} value
- @return {ComputedProperty} computed property which returns true if
- the original value for property is greater than given value.
+ @return {ComputedProperty} computed property which returns true if the
+ original value for property is greater than given value.
@public
*/
export function gt(dependentKey, value) {
@@ -356,14 +546,35 @@ export function gt(dependentKey, value) {
}
/**
- A computed property that returns true if the provided dependent property
- is greater than or equal to the provided value.
+ A computed property that returns true if the provided dependent property is
+ greater than or equal to the provided value.
+
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { gte } from '@ember/object/computed';
+
+ class Hamster {
+ @gte('numBananas', 10) hasTooManyBananas;
+ }
- Example
+ let hamster = new Hamster();
+
+ hamster.hasTooManyBananas; // false
+
+ set(hamster, 'numBananas', 3);
+ hamster.hasTooManyBananas; // false
+
+ set(hamster, 'numBananas', 10);
+ hamster.hasTooManyBananas; // true
+ ```
+
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { gte } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
hasTooManyBananas: gte('numBananas', 10)
@@ -371,11 +582,13 @@ export function gt(dependentKey, value) {
let hamster = Hamster.create();
- hamster.get('hasTooManyBananas'); // false
- hamster.set('numBananas', 3);
- hamster.get('hasTooManyBananas'); // false
- hamster.set('numBananas', 10);
- hamster.get('hasTooManyBananas'); // true
+ hamster.hasTooManyBananas; // false
+
+ set(hamster, 'numBananas', 3);
+ hamster.hasTooManyBananas; // false
+
+ set(hamster, 'numBananas', 10);
+ hamster.hasTooManyBananas; // true
```
@method gte
@@ -383,8 +596,8 @@ export function gt(dependentKey, value) {
@for @ember/object/computed
@param {String} dependentKey
@param {Number} value
- @return {ComputedProperty} computed property which returns true if
- the original value for property is greater or equal then given value.
+ @return {ComputedProperty} computed property which returns true if the
+ original value for property is greater or equal then given value.
@public
*/
export function gte(dependentKey, value) {
@@ -394,14 +607,35 @@ export function gte(dependentKey, value) {
}
/**
- A computed property that returns true if the provided dependent property
- is less than the provided value.
+ A computed property that returns true if the provided dependent property is
+ less than the provided value.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { lt } from '@ember/object/computed';
+
+ class Hamster {
+ @lt('numBananas', 3) needsMoreBananas;
+ }
+
+ let hamster = new Hamster();
+
+ hamster.needsMoreBananas; // true
+
+ set(hamster, 'numBananas', 3);
+ hamster.needsMoreBananas; // false
+
+ set(hamster, 'numBananas', 2);
+ hamster.needsMoreBananas; // true
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { lt } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
needsMoreBananas: lt('numBananas', 3)
@@ -409,11 +643,13 @@ export function gte(dependentKey, value) {
let hamster = Hamster.create();
- hamster.get('needsMoreBananas'); // true
- hamster.set('numBananas', 3);
- hamster.get('needsMoreBananas'); // false
- hamster.set('numBananas', 2);
- hamster.get('needsMoreBananas'); // true
+ hamster.needsMoreBananas; // true
+
+ set(hamster, 'numBananas', 3);
+ hamster.needsMoreBananas; // false
+
+ set(hamster, 'numBananas', 2);
+ hamster.needsMoreBananas; // true
```
@method lt
@@ -421,8 +657,8 @@ export function gte(dependentKey, value) {
@for @ember/object/computed
@param {String} dependentKey
@param {Number} value
- @return {ComputedProperty} computed property which returns true if
- the original value for property is less then given value.
+ @return {ComputedProperty} computed property which returns true if the
+ original value for property is less then given value.
@public
*/
export function lt(dependentKey, value) {
@@ -432,14 +668,35 @@ export function lt(dependentKey, value) {
}
/**
- A computed property that returns true if the provided dependent property
- is less than or equal to the provided value.
+ A computed property that returns true if the provided dependent property is
+ less than or equal to the provided value.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { lte } from '@ember/object/computed';
+
+ class Hamster {
+ @lte('numBananas', 3) needsMoreBananas;
+ }
+
+ let hamster = new Hamster();
+
+ hamster.needsMoreBananas; // true
+
+ set(hamster, 'numBananas', 5);
+ hamster.needsMoreBananas; // false
+
+ set(hamster, 'numBananas', 3);
+ hamster.needsMoreBananas; // true
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { lte } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
needsMoreBananas: lte('numBananas', 3)
@@ -447,11 +704,13 @@ export function lt(dependentKey, value) {
let hamster = Hamster.create();
- hamster.get('needsMoreBananas'); // true
- hamster.set('numBananas', 5);
- hamster.get('needsMoreBananas'); // false
- hamster.set('numBananas', 3);
- hamster.get('needsMoreBananas'); // true
+ hamster.needsMoreBananas; // true
+
+ set(hamster, 'numBananas', 5);
+ hamster.needsMoreBananas; // false
+
+ set(hamster, 'numBananas', 3);
+ hamster.needsMoreBananas; // true
```
@method lte
@@ -459,8 +718,8 @@ export function lt(dependentKey, value) {
@for @ember/object/computed
@param {String} dependentKey
@param {Number} value
- @return {ComputedProperty} computed property which returns true if
- the original value for property is less or equal than given value.
+ @return {ComputedProperty} computed property which returns true if the
+ original value for property is less or equal than given value.
@public
*/
export function lte(dependentKey, value) {
@@ -470,19 +729,46 @@ export function lte(dependentKey, value) {
}
/**
- A computed property that performs a logical `and` on the
- original values for the provided dependent properties.
+ A computed property that performs a logical `and` on the original values for
+ the provided dependent properties.
- You may pass in more than two properties and even use
- property brace expansion. The computed property will
- return the first falsy value or last truthy value
- just like JavaScript's `&&` operator.
+ You may pass in more than two properties and even use property brace
+ expansion. The computed property will return the first falsy value or last
+ truthy value just like JavaScript's `&&` operator.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { and } from '@ember/object/computed';
+
+ class Hamster {
+ @and('hasTent', 'hasBackpack') readyForCamp;
+ @and('hasWalkingStick', 'hasBackpack') readyForHike;
+ }
+
+ let tomster = new Hamster();
+
+ tomster.readyForCamp; // false
+
+ set(tomster, 'hasTent', true);
+ tomster.readyForCamp; // false
+
+ set(tomster, 'hasBackpack', true);
+ tomster.readyForCamp; // true
+
+ set(tomster, 'hasBackpack', 'Yes');
+ tomster.readyForCamp; // 'Yes'
+
+ set(tomster, 'hasWalkingStick', null);
+ tomster.readyForHike; // null
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { and } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
readyForCamp: and('hasTent', 'hasBackpack'),
@@ -491,116 +777,196 @@ export function lte(dependentKey, value) {
let tomster = Hamster.create();
- tomster.get('readyForCamp'); // false
- tomster.set('hasTent', true);
- tomster.get('readyForCamp'); // false
- tomster.set('hasBackpack', true);
- tomster.get('readyForCamp'); // true
- tomster.set('hasBackpack', 'Yes');
- tomster.get('readyForCamp'); // 'Yes'
- tomster.set('hasWalkingStick', null);
- tomster.get('readyForHike'); // null
+ tomster.readyForCamp; // false
+
+ set(tomster, 'hasTent', true);
+ tomster.readyForCamp; // false
+
+ set(tomster, 'hasBackpack', true);
+ tomster.readyForCamp; // true
+
+ set(tomster, 'hasBackpack', 'Yes');
+ tomster.readyForCamp; // 'Yes'
+
+ set(tomster, 'hasWalkingStick', null);
+ tomster.readyForHike; // null
```
@method and
@static
@for @ember/object/computed
@param {String} dependentKey*
- @return {ComputedProperty} computed property which performs
- a logical `and` on the values of all the original values for properties.
+ @return {ComputedProperty} computed property which performs a logical `and` on
+ the values of all the original values for properties.
@public
*/
export const and = generateComputedWithPredicate('and', value => value);
/**
- A computed property which performs a logical `or` on the
- original values for the provided dependent properties.
+ A computed property which performs a logical `or` on the original values for
+ the provided dependent properties.
- You may pass in more than two properties and even use
- property brace expansion. The computed property will
- return the first truthy value or last falsy value just
- like JavaScript's `||` operator.
+ You may pass in more than two properties and even use property brace
+ expansion. The computed property will return the first truthy value or last
+ falsy value just like JavaScript's `||` operator.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { or } from '@ember/object/computed';
+
+ let Hamster = EmberObject.extend({
+ @or('hasJacket', 'hasUmbrella') readyForRain;
+ @or('hasSunscreen', 'hasUmbrella') readyForBeach;
+ });
+
+ let tomster = new Hamster();
+
+ tomster.readyForRain; // undefined
+
+ set(tomster, 'hasUmbrella', true);
+ tomster.readyForRain; // true
+
+ set(tomster, 'hasJacket', 'Yes');
+ tomster.readyForRain; // 'Yes'
+
+ set(tomster, 'hasSunscreen', 'Check');
+ tomster.readyForBeach; // 'Check'
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { or } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
readyForRain: or('hasJacket', 'hasUmbrella'),
- readyForBeach: or('{hasSunscreen,hasUmbrella}')
+ readyForBeach: or('hasSunscreen', 'hasUmbrella')
});
let tomster = Hamster.create();
- tomster.get('readyForRain'); // undefined
- tomster.set('hasUmbrella', true);
- tomster.get('readyForRain'); // true
- tomster.set('hasJacket', 'Yes');
- tomster.get('readyForRain'); // 'Yes'
- tomster.set('hasSunscreen', 'Check');
- tomster.get('readyForBeach'); // 'Check'
+ tomster.readyForRain; // undefined
+
+ set(tomster, 'hasUmbrella', true);
+ tomster.readyForRain; // true
+
+ set(tomster, 'hasJacket', 'Yes');
+ tomster.readyForRain; // 'Yes'
+
+ set(tomster, 'hasSunscreen', 'Check');
+ tomster.readyForBeach; // 'Check'
```
@method or
@static
@for @ember/object/computed
@param {String} dependentKey*
- @return {ComputedProperty} computed property which performs
- a logical `or` on the values of all the original values for properties.
+ @return {ComputedProperty} computed property which performs a logical `or` on
+ the values of all the original values for properties.
@public
*/
export const or = generateComputedWithPredicate('or', value => !value);
/**
- Creates a new property that is an alias for another property
- on an object. Calls to `get` or `set` this property behave as
- though they were called on the original property.
+ Creates a new property that is an alias for another property on an object.
+ Calls to `get` or `set` this property behave as though they were called on the
+ original property.
+
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { alias } from '@ember/object/computed';
+
+ class Person {
+ name = 'Alex Matchneer';
+
+ @alias('name') nomen;
+ }
+
+ let alex = new Person();
+
+ alex.nomen; // 'Alex Matchneer'
+ alex.name; // 'Alex Matchneer'
+
+ set(alex, 'nomen', '@machty');
+ alex.name; // '@machty'
+ ```
+
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { alias } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Person = EmberObject.extend({
name: 'Alex Matchneer',
+
nomen: alias('name')
});
let alex = Person.create();
- alex.get('nomen'); // 'Alex Matchneer'
- alex.get('name'); // 'Alex Matchneer'
+ alex.nomen; // 'Alex Matchneer'
+ alex.name; // 'Alex Matchneer'
- alex.set('nomen', '@machty');
- alex.get('name'); // '@machty'
+ set(alex, 'nomen', '@machty');
+ alex.name; // '@machty'
```
@method alias
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which creates an
- alias to the original value for property.
+ @return {ComputedProperty} computed property which creates an alias to the
+ original value for property.
@public
*/
/**
Where `computed.alias` aliases `get` and `set`, and allows for bidirectional
data flow, `computed.oneWay` only provides an aliased `get`. The `set` will
- not mutate the upstream property, rather causes the current property to
- become the value set. This causes the downstream property to permanently
- diverge from the upstream property.
+ not mutate the upstream property, rather causes the current property to become
+ the value set. This causes the downstream property to permanently diverge from
+ the upstream property.
+
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { oneWay }from '@ember/object/computed';
+
+ class User {
+ constructor(firstName, lastName) {
+ set(this, 'firstName', firstName);
+ set(this, 'lastName', lastName);
+ }
+
+ @oneWay('firstName') nickName;
+ }
- Example
+ let teddy = new User('Teddy', 'Zeenny');
+
+ teddy.nickName; // 'Teddy'
+
+ set(teddy, 'nickName', 'TeddyBear');
+ teddy.firstName; // 'Teddy'
+ teddy.nickName; // 'TeddyBear'
+ ```
+
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { oneWay } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let User = EmberObject.extend({
firstName: null,
lastName: null,
+
nickName: oneWay('firstName')
});
@@ -609,17 +975,19 @@ export const or = generateComputedWithPredicate('or', value => !value);
lastName: 'Zeenny'
});
- teddy.get('nickName'); // 'Teddy'
- teddy.set('nickName', 'TeddyBear'); // 'TeddyBear'
- teddy.get('firstName'); // 'Teddy'
+ teddy.nickName; // 'Teddy'
+
+ set(teddy, 'nickName', 'TeddyBear'); // 'TeddyBear'
+ teddy.firstName; // 'Teddy'
+ teddy.nickName; // 'TeddyBear'
```
@method oneWay
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which creates a
- one way computed property to the original value for property.
+ @return {ComputedProperty} computed property which creates a one way computed
+ property to the original value for property.
@public
*/
export function oneWay(dependentKey) {
@@ -627,15 +995,15 @@ export function oneWay(dependentKey) {
}
/**
- This is a more semantically meaningful alias of `computed.oneWay`,
- whose name is somewhat ambiguous as to which direction the data flows.
+ This is a more semantically meaningful alias of `computed.oneWay`, whose name
+ is somewhat ambiguous as to which direction the data flows.
@method reads
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which creates a
- one way computed property to the original value for property.
+ @return {ComputedProperty} computed property which creates a one way computed
+ property to the original value for property.
@public
*/
@@ -646,15 +1014,41 @@ export function oneWay(dependentKey) {
This prevents the reverse flow, and also throws an exception when it occurs.
- Example
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { readOnly } from '@ember/object/computed';
+
+ class User {
+ constructor(firstName, lastName) {
+ set(this, 'firstName', firstName);
+ set(this, 'lastName', lastName);
+ }
+
+ @readOnly('firstName') nickName;
+ });
+
+ let teddy = new User('Teddy', 'Zeenny');
+
+ teddy.nickName; // 'Teddy'
+
+ set(teddy, 'nickName', 'TeddyBear'); // throws Exception
+ // throw new EmberError('Cannot Set: nickName on: ' );`
+
+ teddy.firstName; // 'Teddy'
+ ```
+
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { readOnly } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let User = EmberObject.extend({
firstName: null,
lastName: null,
+
nickName: readOnly('firstName')
});
@@ -663,18 +1057,20 @@ export function oneWay(dependentKey) {
lastName: 'Zeenny'
});
- teddy.get('nickName'); // 'Teddy'
- teddy.set('nickName', 'TeddyBear'); // throws Exception
+ teddy.nickName; // 'Teddy'
+
+ set(teddy, 'nickName', 'TeddyBear'); // throws Exception
// throw new EmberError('Cannot Set: nickName on: ' );`
- teddy.get('firstName'); // 'Teddy'
+
+ teddy.firstName; // 'Teddy'
```
@method readOnly
@static
@for @ember/object/computed
@param {String} dependentKey
- @return {ComputedProperty} computed property which creates a
- one way computed property to the original value for property.
+ @return {ComputedProperty} computed property which creates a one way computed
+ property to the original value for property.
@since 1.5.0
@public
*/
@@ -683,14 +1079,35 @@ export function readOnly(dependentKey) {
}
/**
- Creates a new property that is an alias for another property
- on an object. Calls to `get` or `set` this property behave as
- though they were called on the original property, but also
- print a deprecation warning.
+ Creates a new property that is an alias for another property on an object.
+ Calls to `get` or `set` this property behave as though they were called on the
+ original property, but also print a deprecation warning.
+
+ Example:
+
+ ```javascript
+ import { set } from '@ember/object';
+ import { deprecatingAlias } from '@ember/object/computed';
+
+ class Hamster {
+ @deprecatingAlias('cavendishCount', {
+ id: 'hamster.deprecate-banana',
+ until: '3.0.0'
+ })
+ bananaCount;
+ }
+
+ let hamster = new Hamster();
+
+ set(hamster, 'bananaCount', 5); // Prints a deprecation warning.
+ hamster.cavendishCount; // 5
+ ```
+
+ Classic Class Example:
```javascript
+ import EmberObject, { set } from '@ember/object';
import { deprecatingAlias } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
bananaCount: deprecatingAlias('cavendishCount', {
@@ -701,8 +1118,8 @@ export function readOnly(dependentKey) {
let hamster = Hamster.create();
- hamster.set('bananaCount', 5); // Prints a deprecation warning.
- hamster.get('cavendishCount'); // 5
+ set(hamster, 'bananaCount', 5); // Prints a deprecation warning.
+ hamster.cavendishCount; // 5
```
@method deprecatingAlias
@@ -710,8 +1127,8 @@ export function readOnly(dependentKey) {
@for @ember/object/computed
@param {String} dependentKey
@param {Object} options Options for `deprecate`.
- @return {ComputedProperty} computed property which creates an
- alias with a deprecation to the original value for property.
+ @return {ComputedProperty} computed property which creates an alias with a
+ deprecation to the original value for property.
@since 1.7.0
@public
*/
diff --git a/packages/@ember/object/lib/computed/reduce_computed_macros.js b/packages/@ember/object/lib/computed/reduce_computed_macros.js
index 63aeef51ac7..88c12734e8d 100644
--- a/packages/@ember/object/lib/computed/reduce_computed_macros.js
+++ b/packages/@ember/object/lib/computed/reduce_computed_macros.js
@@ -54,14 +54,47 @@ function multiArrayMacro(_dependentKeys, callback, name) {
}
/**
- A computed property that returns the sum of the values
- in the dependent array.
+ A computed property that returns the sum of the values in the dependent array.
+
+ Example:
+
+ ```javascript
+ import { sum } from '@ember/object/computed';
+
+ class Invoice {
+ lineItems = [1.00, 2.50, 9.99];
+
+ @sum('lineItems') total;
+ }
+
+ let invoice = new Invoice();
+
+ invoice.total; // 13.49
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject from '@ember/object';
+ import { sum } from '@ember/object/computed';
+
+ let Invoice = EmberObject.extend({
+ lineItems: [1.00, 2.50, 9.99],
+
+ total: sum('lineItems')
+ })
+
+ let invoice = Invoice.create();
+
+ invoice.total; // 13.49
+ ```
@method sum
@for @ember/object/computed
@static
@param {String} dependentKey
- @return {ComputedProperty} computes the sum of all values in the dependentKey's array
+ @return {ComputedProperty} computes the sum of all values in the
+ dependentKey's array
@since 1.4.0
@public
*/
@@ -70,13 +103,52 @@ export function sum(dependentKey) {
}
/**
- A computed property that calculates the maximum value in the
- dependent array. This will return `-Infinity` when the dependent
- array is empty.
+ A computed property that calculates the maximum value in the dependent array.
+ This will return `-Infinity` when the dependent array is empty.
+
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { mapBy, max } from '@ember/object/computed';
+
+ class Person {
+ children = [];
+
+ @mapBy('children', 'age') childAges;
+ @max('childAges') maxChildAge;
+ }
+
+ let lordByron = new Person();
+
+ lordByron.maxChildAge; // -Infinity
+
+ set(lordByron, 'children', [
+ {
+ name: 'Augusta Ada Byron',
+ age: 7
+ }
+ ]);
+ lordByron.maxChildAge; // 7
+
+ set(lordByron, 'children', [
+ ...lordByron.children,
+ {
+ name: 'Allegra Byron',
+ age: 5
+ }, {
+ name: 'Elizabeth Medora Leigh',
+ age: 8
+ }
+ ]);
+ lordByron.maxChildAge; // 8
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { mapBy, max } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Person = EmberObject.extend({
childAges: mapBy('children', 'age'),
@@ -85,33 +157,40 @@ export function sum(dependentKey) {
let lordByron = Person.create({ children: [] });
- lordByron.get('maxChildAge'); // -Infinity
- lordByron.get('children').pushObject({
- name: 'Augusta Ada Byron', age: 7
- });
- lordByron.get('maxChildAge'); // 7
- lordByron.get('children').pushObjects([{
- name: 'Allegra Byron',
- age: 5
- }, {
- name: 'Elizabeth Medora Leigh',
- age: 8
- }]);
- lordByron.get('maxChildAge'); // 8
+ lordByron.maxChildAge; // -Infinity
+
+ set(lordByron, 'children', [
+ {
+ name: 'Augusta Ada Byron',
+ age: 7
+ }
+ ]);
+ lordByron.maxChildAge; // 7
+
+ set(lordByron, 'children', [
+ ...lordByron.children,
+ {
+ name: 'Allegra Byron',
+ age: 5
+ }, {
+ name: 'Elizabeth Medora Leigh',
+ age: 8
+ }
+ ]);
+ lordByron.maxChildAge; // 8
```
- If the types of the arguments are not numbers,
- they will be converted to numbers and the type
- of the return value will always be `Number`.
- For example, the max of a list of Date objects will be
- the highest timestamp as a `Number`.
+ If the types of the arguments are not numbers, they will be converted to
+ numbers and the type of the return value will always be `Number`. For example,
+ the max of a list of Date objects will be the highest timestamp as a `Number`.
This behavior is consistent with `Math.max`.
@method max
@for @ember/object/computed
@static
@param {String} dependentKey
- @return {ComputedProperty} computes the largest value in the dependentKey's array
+ @return {ComputedProperty} computes the largest value in the dependentKey's
+ array
@public
*/
export function max(dependentKey) {
@@ -119,13 +198,52 @@ export function max(dependentKey) {
}
/**
- A computed property that calculates the minimum value in the
- dependent array. This will return `Infinity` when the dependent
- array is empty.
+ A computed property that calculates the minimum value in the dependent array.
+ This will return `Infinity` when the dependent array is empty.
+
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { mapBy, min } from '@ember/object/computed';
+
+ class Person {
+ children = [];
+
+ @mapBy('children', 'age') childAges;
+ @min('childAges') minChildAge;
+ }
+
+ let lordByron = Person.create({ children: [] });
+
+ lordByron.minChildAge; // Infinity
+
+ set(lordByron, 'children', [
+ {
+ name: 'Augusta Ada Byron',
+ age: 7
+ }
+ ]);
+ lordByron.minChildAge; // 7
+
+ set(lordByron, 'children', [
+ ...lordByron.children,
+ {
+ name: 'Allegra Byron',
+ age: 5
+ }, {
+ name: 'Elizabeth Medora Leigh',
+ age: 8
+ }
+ ]);
+ lordByron.minChildAge; // 5
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { mapBy, min } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Person = EmberObject.extend({
childAges: mapBy('children', 'age'),
@@ -134,26 +252,32 @@ export function max(dependentKey) {
let lordByron = Person.create({ children: [] });
- lordByron.get('minChildAge'); // Infinity
- lordByron.get('children').pushObject({
- name: 'Augusta Ada Byron', age: 7
- });
- lordByron.get('minChildAge'); // 7
- lordByron.get('children').pushObjects([{
- name: 'Allegra Byron',
- age: 5
- }, {
- name: 'Elizabeth Medora Leigh',
- age: 8
- }]);
- lordByron.get('minChildAge'); // 5
+ lordByron.minChildAge; // Infinity
+
+ set(lordByron, 'children', [
+ {
+ name: 'Augusta Ada Byron',
+ age: 7
+ }
+ ]);
+ lordByron.minChildAge; // 7
+
+ set(lordByron, 'children', [
+ ...lordByron.children,
+ {
+ name: 'Allegra Byron',
+ age: 5
+ }, {
+ name: 'Elizabeth Medora Leigh',
+ age: 8
+ }
+ ]);
+ lordByron.minChildAge; // 5
```
- If the types of the arguments are not numbers,
- they will be converted to numbers and the type
- of the return value will always be `Number`.
- For example, the min of a list of Date objects will be
- the lowest timestamp as a `Number`.
+ If the types of the arguments are not numbers, they will be converted to
+ numbers and the type of the return value will always be `Number`. For example,
+ the min of a list of Date objects will be the lowest timestamp as a `Number`.
This behavior is consistent with `Math.min`.
@method min
@@ -170,23 +294,45 @@ export function min(dependentKey) {
/**
Returns an array mapped via the callback
- The callback method you provide should have the following signature.
- `item` is the current item in the iteration.
- `index` is the integer index of the current item in the iteration.
+ The callback method you provide should have the following signature:
+ - `item` is the current item in the iteration.
+ - `index` is the integer index of the current item in the iteration.
```javascript
- function(item, index);
+ function mapCallback(item, index);
```
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
import { map } from '@ember/object/computed';
+
+ class Hamster {
+ constructor(chores) {
+ set(this, 'chores', chores);
+ }
+
+ @map('chores', function(chore, index) {
+ return `${chore.toUpperCase()}!`;
+ })
+ excitingChores;
+ });
+
+ let hamster = new Hamster(['clean', 'write more unit tests']);
+
+ hamster.excitingChores; // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { map } from '@ember/object/computed';
let Hamster = EmberObject.extend({
excitingChores: map('chores', function(chore, index) {
- return chore.toUpperCase() + '!';
+ return `${chore.toUpperCase()}!`;
})
});
@@ -194,42 +340,47 @@ export function min(dependentKey) {
chores: ['clean', 'write more unit tests']
});
- hamster.get('excitingChores'); // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
+ hamster.excitingChores; // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
```
You can optionally pass an array of additional dependent keys as the second
parameter to the macro, if your map function relies on any external values:
```javascript
+ import { set } from '@ember/object';
import { map } from '@ember/object/computed';
- import EmberObject from '@ember/object';
- let Hamster = EmberObject.extend({
- excitingChores: map('chores', ['shouldUpperCase'], function(chore, index) {
+ class Hamster {
+ shouldUpperCase = false;
+
+ constructor(chores) {
+ set(this, 'chores', chores);
+ }
+
+ @map('chores', ['shouldUpperCase'], function(chore, index) {
if (this.shouldUpperCase) {
- return chore.toUpperCase() + '!';
+ return `${chore.toUpperCase()}!`;
} else {
- return chore + '!';
+ return `${chore}!`;
}
})
- });
+ excitingChores;
+ }
- let hamster = Hamster.create({
- shouldUpperCase: false,
+ let hamster = new Hamster(['clean', 'write more unit tests']);
- chores: ['clean', 'write more unit tests']
- });
+ hamster.excitingChores; // ['clean!', 'write more unit tests!']
- hamster.get('excitingChores'); // ['clean!', 'write more unit tests!']
- hamster.set('shouldUpperCase', true);
- hamster.get('excitingChores'); // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
+ set(hamster, 'shouldUpperCase', true);
+ hamster.excitingChores; // ['CLEAN!', 'WRITE MORE UNIT TESTS!']
```
@method map
@for @ember/object/computed
@static
@param {String} dependentKey
- @param {Array} [additionalDependentKeys] optional array of additional dependent keys
+ @param {Array} [additionalDependentKeys] optional array of additional
+ dependent keys
@param {Function} callback
@return {ComputedProperty} an array mapped via the callback
@public
@@ -258,9 +409,48 @@ export function map(dependentKey, additionalDependentKeys, callback) {
/**
Returns an array mapped to the specified key.
+ Example:
+
```javascript
+ import { set } from '@ember/object';
+ import { mapBy } from '@ember/object/computed';
+
+ class Person {
+ children = [];
+
+ @mapBy('children', 'age') childAges;
+ }
+
+ let lordByron = new Person();
+
+ lordByron.childAges; // []
+
+ set(lordByron, 'children', [
+ {
+ name: 'Augusta Ada Byron',
+ age: 7
+ }
+ ]);
+ lordByron.childAges; // [7]
+
+ set(lordByron, 'children', [
+ ...lordByron.children,
+ {
+ name: 'Allegra Byron',
+ age: 5
+ }, {
+ name: 'Elizabeth Medora Leigh',
+ age: 8
+ }
+ ]);
+ lordByron.childAges; // [7, 5, 8]
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { mapBy } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Person = EmberObject.extend({
childAges: mapBy('children', 'age')
@@ -268,17 +458,27 @@ export function map(dependentKey, additionalDependentKeys, callback) {
let lordByron = Person.create({ children: [] });
- lordByron.get('childAges'); // []
- lordByron.get('children').pushObject({ name: 'Augusta Ada Byron', age: 7 });
- lordByron.get('childAges'); // [7]
- lordByron.get('children').pushObjects([{
- name: 'Allegra Byron',
- age: 5
- }, {
- name: 'Elizabeth Medora Leigh',
- age: 8
- }]);
- lordByron.get('childAges'); // [7, 5, 8]
+ lordByron.childAges; // []
+
+ set(lordByron, 'children', [
+ {
+ name: 'Augusta Ada Byron',
+ age: 7
+ }
+ ]);
+ lordByron.childAges; // [7]
+
+ set(lordByron, 'children', [
+ ...lordByron.children,
+ {
+ name: 'Allegra Byron',
+ age: 5
+ }, {
+ name: 'Elizabeth Medora Leigh',
+ age: 8
+ }
+ ]);
+ lordByron.childAges; // [7, 5, 8]
```
@method mapBy
@@ -306,18 +506,46 @@ export function mapBy(dependentKey, propertyKey) {
/**
Filters the array by the callback.
- The callback method you provide should have the following signature.
- `item` is the current item in the iteration.
- `index` is the integer index of the current item in the iteration.
- `array` is the dependant array itself.
+ The callback method you provide should have the following signature:
+ - `item` is the current item in the iteration.
+ - `index` is the integer index of the current item in the iteration.
+ - `array` is the dependant array itself.
```javascript
- function(item, index, array);
+ function filterCallback(item, index, array);
```
+ Example:
+
```javascript
+ import { set } from '@ember/object';
import { filter } from '@ember/object/computed';
+
+ class Hamster {
+ constructor(chores) {
+ set(this, 'chores', chores);
+ }
+
+ @filter('chores', function(chore, index, array) {
+ return !chore.done;
+ })
+ remainingChores;
+ }
+
+ let hamster = Hamster.create([
+ { name: 'cook', done: true },
+ { name: 'clean', done: true },
+ { name: 'write more unit tests', done: false }
+ ]);
+
+ hamster.remainingChores; // [{name: 'write more unit tests', done: false}]
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { filter } from '@ember/object/computed';
let Hamster = EmberObject.extend({
remainingChores: filter('chores', function(chore, index, array) {
@@ -333,32 +561,36 @@ export function mapBy(dependentKey, propertyKey) {
]
});
- hamster.get('remainingChores'); // [{name: 'write more unit tests', done: false}]
+ hamster.remainingChores; // [{name: 'write more unit tests', done: false}]
```
- You can also use `@each.property` in your dependent key, the callback will still use the underlying array:
+ You can also use `@each.property` in your dependent key, the callback will
+ still use the underlying array:
```javascript
- import { A } from '@ember/array';
+ import { set } from '@ember/object';
import { filter } from '@ember/object/computed';
- import EmberObject from '@ember/object';
- let Hamster = EmberObject.extend({
- remainingChores: filter('chores.@each.done', function(chore, index, array) {
- return !chore.get('done');
+ class Hamster {
+ constructor(chores) {
+ set(this, 'chores', chores);
+ }
+
+ @filter('chores.@each.done', function(chore, index, array) {
+ return !chore.done;
})
- });
+ remainingChores;
+ }
- let hamster = Hamster.create({
- chores: A([
- EmberObject.create({ name: 'cook', done: true }),
- EmberObject.create({ name: 'clean', done: true }),
- EmberObject.create({ name: 'write more unit tests', done: false })
- ])
- });
- hamster.get('remainingChores'); // [{name: 'write more unit tests', done: false}]
- hamster.get('chores').objectAt(2).set('done', true);
- hamster.get('remainingChores'); // []
+ let hamster = new Hamster([
+ { name: 'cook', done: true },
+ { name: 'clean', done: true },
+ { name: 'write more unit tests', done: false }
+ ]);
+ hamster.remainingChores; // [{name: 'write more unit tests', done: false}]
+
+ set(hamster.chores[2], 'done', true);
+ hamster.remainingChores; // []
```
Finally, you can optionally pass an array of additional dependent keys as the
@@ -367,25 +599,27 @@ export function mapBy(dependentKey, propertyKey) {
```javascript
import { filter } from '@ember/object/computed';
- import EmberObject from '@ember/object';
- let Hamster = EmberObject.extend({
- remainingChores: filter('chores', ['doneKey'], function(chore, index, array) {
+ class Hamster {
+ constructor(chores) {
+ set(this, 'chores', chores);
+ }
+
+ doneKey = 'finished';
+
+ @filter('chores', ['doneKey'], function(chore, index, array) {
return !chore[this.doneKey];
})
- });
+ remainingChores;
+ }
- let hamster = Hamster.create({
- doneKey: 'finished'
+ let hamster = new Hamster([
+ { name: 'cook', finished: true },
+ { name: 'clean', finished: true },
+ { name: 'write more unit tests', finished: false }
+ ]);
- chores: [
- { name: 'cook', finished: true },
- { name: 'clean', finished: true },
- { name: 'write more unit tests', finished: false }
- ]
- });
-
- hamster.get('remainingChores'); // [{name: 'write more unit tests', finished: false}]
+ hamster.remainingChores; // [{name: 'write more unit tests', finished: false}]
```
@method filter
@@ -419,11 +653,36 @@ export function filter(dependentKey, additionalDependentKeys, callback) {
}
/**
- Filters the array by the property and value
+ Filters the array by the property and value.
+
+ Example:
```javascript
+ import { set } from '@ember/object';
import { filterBy } from '@ember/object/computed';
+
+ class Hamster {
+ constructor(chores) {
+ set(this, 'chores', chores);
+ }
+
+ @filterBy('chores', 'done', false) remainingChores;
+ }
+
+ let hamster = new Hamster([
+ { name: 'cook', done: true },
+ { name: 'clean', done: true },
+ { name: 'write more unit tests', done: false }
+ ]);
+
+ hamster.remainingChores; // [{ name: 'write more unit tests', done: false }]
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { filterBy } from '@ember/object/computed';
let Hamster = EmberObject.extend({
remainingChores: filterBy('chores', 'done', false)
@@ -437,7 +696,7 @@ export function filter(dependentKey, additionalDependentKeys, callback) {
]
});
- hamster.get('remainingChores'); // [{ name: 'write more unit tests', done: false }]
+ hamster.remainingChores; // [{ name: 'write more unit tests', done: false }]
```
@method filterBy
@@ -466,14 +725,38 @@ export function filterBy(dependentKey, propertyKey, value) {
}
/**
- A computed property which returns a new array with all the unique
- elements from one or more dependent arrays.
+ A computed property which returns a new array with all the unique elements
+ from one or more dependent arrays.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
import { uniq } from '@ember/object/computed';
+
+ class Hamster {
+ constructor(fruits) {
+ set(this, 'fruits', fruits);
+ }
+
+ @uniq('fruits') uniqueFruits;
+ }
+
+ let hamster = new Hamster([
+ 'banana',
+ 'grape',
+ 'kale',
+ 'banana'
+ ]);
+
+ hamster.uniqueFruits; // ['banana', 'grape', 'kale']
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { uniq } from '@ember/object/computed';
let Hamster = EmberObject.extend({
uniqueFruits: uniq('fruits')
@@ -488,7 +771,7 @@ export function filterBy(dependentKey, propertyKey, value) {
]
});
- hamster.get('uniqueFruits'); // ['banana', 'grape', 'kale']
+ hamster.uniqueFruits; // ['banana', 'grape', 'kale']
```
@method uniq
@@ -525,18 +808,43 @@ export function uniq(...args) {
}
/**
- A computed property which returns a new array with all the unique
- elements from an array, with uniqueness determined by specific key.
+ A computed property which returns a new array with all the unique elements
+ from an array, with uniqueness determined by specific key.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
import { uniqBy } from '@ember/object/computed';
+
+ class Hamster {
+ constructor(fruits) {
+ set(this, 'fruits', fruits);
+ }
+
+ @uniqBy('fruits', 'id') uniqueFruits;
+ }
+
+ let hamster = new Hamster([
+ { id: 1, 'banana' },
+ { id: 2, 'grape' },
+ { id: 3, 'peach' },
+ { id: 1, 'banana' }
+ ]);
+
+ hamster.uniqueFruits; // [ { id: 1, 'banana' }, { id: 2, 'grape' }, { id: 3, 'peach' }]
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { uniqBy } from '@ember/object/computed';
let Hamster = EmberObject.extend({
uniqueFruits: uniqBy('fruits', 'id')
});
+
let hamster = Hamster.create({
fruits: [
{ id: 1, 'banana' },
@@ -545,7 +853,8 @@ export function uniq(...args) {
{ id: 1, 'banana' }
]
});
- hamster.get('uniqueFruits'); // [ { id: 1, 'banana' }, { id: 2, 'grape' }, { id: 3, 'peach' }]
+
+ hamster.uniqueFruits; // [ { id: 1, 'banana' }, { id: 2, 'grape' }, { id: 3, 'peach' }]
```
@method uniqBy
@@ -570,14 +879,47 @@ export function uniqBy(dependentKey, propertyKey) {
}
/**
- A computed property which returns a new array with all the unique
- elements from one or more dependent arrays.
+ A computed property which returns a new array with all the unique elements
+ from one or more dependent arrays.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
import { union } from '@ember/object/computed';
+
+ class Hamster {
+ constructor(fruits, vegetables) {
+ set(this, 'fruits', fruits);
+ set(this, 'vegetables', vegetables);
+ }
+
+ @union('fruits', 'vegetables') ediblePlants;
+ });
+
+ let hamster = new, Hamster(
+ [
+ 'banana',
+ 'grape',
+ 'kale',
+ 'banana',
+ 'tomato'
+ ],
+ [
+ 'tomato',
+ 'carrot',
+ 'lettuce'
+ ]
+ );
+
+ hamster.uniqueFruits; // ['banana', 'grape', 'kale', 'tomato', 'carrot', 'lettuce']
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { union } from '@ember/object/computed';
let Hamster = EmberObject.extend({
uniqueFruits: union('fruits', 'vegetables')
@@ -598,15 +940,15 @@ export function uniqBy(dependentKey, propertyKey) {
]
});
- hamster.get('uniqueFruits'); // ['banana', 'grape', 'kale', 'tomato', 'carrot', 'lettuce']
+ hamster.uniqueFruits; // ['banana', 'grape', 'kale', 'tomato', 'carrot', 'lettuce']
```
@method union
@for @ember/object/computed
@static
@param {String} propertyKey*
- @return {ComputedProperty} computes a new array with all the
- unique elements from one or more dependent arrays.
+ @return {ComputedProperty} computes a new array with all the unique elements
+ from one or more dependent arrays.
@public
*/
export let union = uniq;
@@ -615,28 +957,53 @@ export let union = uniq;
A computed property which returns a new array with all the elements
two or more dependent arrays have in common.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
import { intersect } from '@ember/object/computed';
+
+ class FriendGroups {
+ constructor(adaFriends, charlesFriends) {
+ set(this, 'adaFriends', adaFriends);
+ set(this, 'charlesFriends', charlesFriends);
+ }
+
+ @intersect('adaFriends', 'charlesFriends') friendsInCommon;
+ }
+
+ let groups = new FriendGroups(
+ ['Charles Babbage', 'John Hobhouse', 'William King', 'Mary Somerville'],
+ ['William King', 'Mary Somerville', 'Ada Lovelace', 'George Peacock']
+ );
+
+ groups.friendsInCommon; // ['William King', 'Mary Somerville']
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { intersect } from '@ember/object/computed';
- let obj = EmberObject.extend({
+ let FriendGroups = EmberObject.extend({
friendsInCommon: intersect('adaFriends', 'charlesFriends')
- }).create({
+ });
+
+ let groups = FriendGroups.create({
adaFriends: ['Charles Babbage', 'John Hobhouse', 'William King', 'Mary Somerville'],
charlesFriends: ['William King', 'Mary Somerville', 'Ada Lovelace', 'George Peacock']
});
- obj.get('friendsInCommon'); // ['William King', 'Mary Somerville']
+ groups.friendsInCommon; // ['William King', 'Mary Somerville']
```
@method intersect
@for @ember/object/computed
@static
@param {String} propertyKey*
- @return {ComputedProperty} computes a new array with all the
- duplicated elements from the dependent arrays
+ @return {ComputedProperty} computes a new array with all the duplicated
+ elements from the dependent arrays
@public
*/
export function intersect(...args) {
@@ -674,29 +1041,62 @@ export function intersect(...args) {
}
/**
- A computed property which returns a new array with all the
- properties from the first dependent array that are not in the second
- dependent array.
+ A computed property which returns a new array with all the properties from the
+ first dependent array that are not in the second dependent array.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
import { setDiff } from '@ember/object/computed';
+
+ class Hamster {
+ constructor(likes, fruits) {
+ set(this, 'likes', likes);
+ set(this, 'fruits', fruits);
+ }
+
+ @setDiff('likes', 'fruits') wants;
+ }
+
+ let hamster = new Hamster(
+ [
+ 'banana',
+ 'grape',
+ 'kale'
+ ],
+ [
+ 'grape',
+ 'kale',
+ ]
+ );
+
+ hamster.wants; // ['banana']
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { setDiff } from '@ember/object/computed';
let Hamster = EmberObject.extend({
- likes: ['banana', 'grape', 'kale'],
wants: setDiff('likes', 'fruits')
});
let hamster = Hamster.create({
+ likes: [
+ 'banana',
+ 'grape',
+ 'kale'
+ ],
fruits: [
'grape',
'kale',
]
});
- hamster.get('wants'); // ['banana']
+ hamster.wants; // ['banana']
```
@method setDiff
@@ -704,9 +1104,8 @@ export function intersect(...args) {
@static
@param {String} setAProperty
@param {String} setBProperty
- @return {ComputedProperty} computes a new array with all the
- items from the first dependent array that are not in the second
- dependent array
+ @return {ComputedProperty} computes a new array with all the items from the
+ first dependent array that are not in the second dependent array
@public
*/
export function setDiff(setAProperty, setBProperty) {
@@ -732,14 +1131,33 @@ export function setDiff(setAProperty, setBProperty) {
}
/**
- A computed property that returns the array of values
- for the provided dependent properties.
+ A computed property that returns the array of values for the provided
+ dependent properties.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
+ import { collect } from '@ember/object/computed';
+
+ class Hamster {
+ @collect('hat', 'shirt') clothes;
+ }
+
+ let hamster = new Hamster();
+
+ hamster.clothes; // [null, null]
+
+ set(hamster, 'hat', 'Camp Hat');
+ set(hamster, 'shirt', 'Camp Shirt');
+ hamster.clothes; // ['Camp Hat', 'Camp Shirt']
+ ```
+
+ Classic Class Example:
+
+ ```javascript
+ import EmberObject, { set } from '@ember/object';
import { collect } from '@ember/object/computed';
- import EmberObject from '@ember/object';
let Hamster = EmberObject.extend({
clothes: collect('hat', 'shirt')
@@ -747,18 +1165,19 @@ export function setDiff(setAProperty, setBProperty) {
let hamster = Hamster.create();
- hamster.get('clothes'); // [null, null]
- hamster.set('hat', 'Camp Hat');
- hamster.set('shirt', 'Camp Shirt');
- hamster.get('clothes'); // ['Camp Hat', 'Camp Shirt']
+ hamster.clothes; // [null, null]
+
+ set(hamster, 'hat', 'Camp Hat');
+ set(hamster, 'shirt', 'Camp Shirt');
+ hamster.clothes; // ['Camp Hat', 'Camp Shirt']
```
@method collect
@for @ember/object/computed
@static
@param {String} dependentKey*
- @return {ComputedProperty} computed property which maps
- values of all passed in properties to an array.
+ @return {ComputedProperty} computed property which maps values of all passed
+ in properties to an array.
@public
*/
export function collect(...dependentKeys) {
@@ -777,9 +1196,9 @@ export function collect(...dependentKeys) {
}
/**
- A computed property which returns a new array with all the
- properties from the first dependent array sorted based on a property
- or sort function. The sort macro can be used in two different ways:
+ A computed property which returns a new array with all the properties from the
+ first dependent array sorted based on a property or sort function. The sort
+ macro can be used in two different ways:
1. By providing a sort callback function
2. By providing an array of keys to sort the array
@@ -788,7 +1207,7 @@ export function collect(...dependentKeys) {
signature:
```javascript
- function(itemA, itemB);
+ function sortCallback(itemA, itemB);
```
- `itemA` the first item to compare.
@@ -803,11 +1222,44 @@ export function collect(...dependentKeys) {
itemB` or `itemA.get( 'foo' ) - itemB.get( 'foo' )` can be used instead of
series of `if`.
- Example
+ Example:
```javascript
+ import { set } from '@ember/object';
import { sort } from '@ember/object/computed';
+
+ class ToDoList {
+ constructor(todos) {
+ set(this, 'todos', todos);
+ }
+
+ // using a custom sort function
+ @sort('todos', function(a, b){
+ if (a.priority > b.priority) {
+ return 1;
+ } else if (a.priority < b.priority) {
+ return -1;
+ }
+
+ return 0;
+ })
+ priorityTodos;
+ }
+
+ let todoList = new ToDoList([
+ { name: 'Unit Test', priority: 2 },
+ { name: 'Documentation', priority: 3 },
+ { name: 'Release', priority: 1 }
+ ]);
+
+ todoList.priorityTodos; // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
+ ```
+
+ Classic Class Example:
+
+ ```javascript
import EmberObject from '@ember/object';
+ import { sort } from '@ember/object/computed';
let ToDoList = EmberObject.extend({
// using a custom sort function
@@ -830,7 +1282,7 @@ export function collect(...dependentKeys) {
]
});
- todoList.get('priorityTodos'); // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
+ todoList.priorityTodos; // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
```
You can also optionally pass an array of additional dependent keys as the
@@ -838,12 +1290,18 @@ export function collect(...dependentKeys) {
could changes:
```js
+ import EmberObject, { set } from '@ember/object';
import { sort } from '@ember/object/computed';
- import EmberObject from '@ember/object';
- let ToDoList = EmberObject.extend({
+ class ToDoList {
+ sortKey = 'priority';
+
+ constructor(todos) {
+ set(this, 'todos', todos);
+ }
+
// using a custom sort function
- sortedTodos: sort('todos', ['sortKey'] function(a, b){
+ @sort('todos', ['sortKey'], function(a, b){
if (a[this.sortKey] > b[this.sortKey]) {
return 1;
} else if (a[this.sortKey] < b[this.sortKey]) {
@@ -852,59 +1310,60 @@ export function collect(...dependentKeys) {
return 0;
})
+ sortedTodos;
});
- let todoList = ToDoList.create({
- sortKey: 'priority',
-
- todos: [
- { name: 'Unit Test', priority: 2 },
- { name: 'Documentation', priority: 3 },
- { name: 'Release', priority: 1 }
- ]
- });
+ let todoList = new ToDoList([
+ { name: 'Unit Test', priority: 2 },
+ { name: 'Documentation', priority: 3 },
+ { name: 'Release', priority: 1 }
+ ]);
- todoList.get('priorityTodos'); // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
+ todoList.priorityTodos; // [{ name:'Release', priority:1 }, { name:'Unit Test', priority:2 }, { name:'Documentation', priority:3 }]
```
In the second form, you should provide the key of the array of sort values as
the second parameter:
```javascript
+ import { set } from '@ember/object';
import { sort } from '@ember/object/computed';
- import EmberObject from '@ember/object';
- let ToDoList = EmberObject.extend({
+ class ToDoList {
+ constructor(todos) {
+ set(this, 'todos', todos);
+ }
+
// using standard ascending sort
- todosSorting: Object.freeze(['name']),
- sortedTodos: sort('todos', 'todosSorting'),
+ todosSorting = ['name'];
+ @sort('todos', 'todosSorting') sortedTodos;
// using descending sort
- todosSortingDesc: Object.freeze(['name:desc']),
- sortedTodosDesc: sort('todos', 'todosSortingDesc'),
- });
+ todosSortingDesc = ['name:desc'];
+ @sort('todos', 'todosSortingDesc') sortedTodosDesc;
+ }
- let todoList = ToDoList.create({
- todos: [
- { name: 'Unit Test', priority: 2 },
- { name: 'Documentation', priority: 3 },
- { name: 'Release', priority: 1 }
- ]
- });
+ let todoList = new ToDoList([
+ { name: 'Unit Test', priority: 2 },
+ { name: 'Documentation', priority: 3 },
+ { name: 'Release', priority: 1 }
+ ]);
- todoList.get('sortedTodos'); // [{ name:'Documentation', priority:3 }, { name:'Release', priority:1 }, { name:'Unit Test', priority:2 }]
- todoList.get('sortedTodosDesc'); // [{ name:'Unit Test', priority:2 }, { name:'Release', priority:1 }, { name:'Documentation', priority:3 }]
+ todoList.sortedTodos; // [{ name:'Documentation', priority:3 }, { name:'Release', priority:1 }, { name:'Unit Test', priority:2 }]
+ todoList.sortedTodosDesc; // [{ name:'Unit Test', priority:2 }, { name:'Release', priority:1 }, { name:'Documentation', priority:3 }]
```
@method sort
@for @ember/object/computed
@static
@param {String} itemsKey
- @param {Array} [additionalDependentKeys] optional array of additional dependent keys
- @param {String or Function} sortDefinition a dependent key to an
- array of sort properties (add `:desc` to the arrays sort properties to sort descending) or a function to use when sorting
- @return {ComputedProperty} computes a new sorted array based
- on the sort property array or callback function
+ @param {Array} [additionalDependentKeys] optional array of additional
+ dependent keys
+ @param {String or Function} sortDefinition a dependent key to an array of sort
+ properties (add `:desc` to the arrays sort properties to sort descending) or a
+ function to use when sorting
+ @return {ComputedProperty} computes a new sorted array based on the sort
+ property array or callback function
@public
*/
export function sort(itemsKey, additionalDependentKeys, sortDefinition) {
diff --git a/packages/@ember/service/index.js b/packages/@ember/service/index.js
index d68a67dabdf..665e0c41514 100644
--- a/packages/@ember/service/index.js
+++ b/packages/@ember/service/index.js
@@ -7,8 +7,8 @@ import { inject as metalInject } from '@ember/-internals/metal';
*/
/**
- Creates a property that lazily looks up a service in the container. There
- are no restrictions as to what objects a service can be injected into.
+ Creates a property that lazily looks up a service in the container. There are
+ no restrictions as to what objects a service can be injected into.
Example:
@@ -16,6 +16,21 @@ import { inject as metalInject } from '@ember/-internals/metal';
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
+ export default class ApplicationRoute extends Route {
+ @service('auth') authManager;
+
+ model() {
+ return this.authManager.findCurrentUser();
+ }
+ }
+ ```
+
+ Classic Class Example:
+
+ ```app/routes/application.js
+ import Route from '@ember/routing/route';
+ import { inject as service } from '@ember/service';
+
export default Route.extend({
authManager: service('auth'),
@@ -26,8 +41,8 @@ import { inject as metalInject } from '@ember/-internals/metal';
```
This example will create an `authManager` property on the application route
- that looks up the `auth` service in the container, making it easily
- accessible in the `model` hook.
+ that looks up the `auth` service in the container, making it easily accessible
+ in the `model` hook.
@method inject
@static