diff --git a/data/pages.yml b/data/pages.yml index baf1e1e06..8cde2de2f 100644 --- a/data/pages.yml +++ b/data/pages.yml @@ -18,6 +18,8 @@ - title: "The Object Model" url: 'object-model' pages: + - title: "Objects in Ember" + url: "index" - title: "Classes and Instances" url: "classes-and-instances" - title: "Reopening Classes and Instances" @@ -30,8 +32,6 @@ url: "observers" - title: "Bindings" url: "bindings" - - title: "Bindings, Observers, Computed Properties: What Do I Use When?" - url: "what-do-i-use-when" - title: "Enumerables" url: 'enumerables' diff --git a/source/object-model/bindings.md b/source/object-model/bindings.md index c6d6f3ac9..2b348ef9c 100644 --- a/source/object-model/bindings.md +++ b/source/object-model/bindings.md @@ -1,8 +1,7 @@ -A binding creates a link between two properties such that when one changes, the -other one is updated to the new value automatically. Bindings can connect -properties on the same object, or across two different objects. Unlike most other -frameworks that include some sort of binding implementation, bindings in -Ember.js can be used with any object, not just between views and models. +Unlike most other frameworks that include some sort of binding implementation, +bindings in Ember.js can be used with any object. That said, bindings are most +often used within the Ember framework itself, and for most problems Ember app +developers face, computed properties are the appropriate solution. The easiest way to create a two-way binding is to use a computed alias, that specifies the path to another object. diff --git a/source/object-model/classes-and-instances.md b/source/object-model/classes-and-instances.md index 75d62388b..87f1b7809 100644 --- a/source/object-model/classes-and-instances.md +++ b/source/object-model/classes-and-instances.md @@ -1,3 +1,7 @@ +As you learn about Ember, you'll see code like `Ember.Component.extend()` and +`DS.Model.extend()`. Here, you'll learn about this `extend()` method, as well +as other major features of the Ember object model. + ### Defining Classes To define a new Ember _class_, call the `extend()` method on @@ -17,10 +21,10 @@ You can also create a _subclass_ from any existing class by calling its `extend()` method. For example, you might want to create a subclass of Ember's built-in `Ember.Component` class: -```app/views/person.js -PersonView = Ember.Component.extend({ - tagName: 'li', - classNameBindings: ['isAdministrator'] +```app/components/todo-item.js +export default Ember.Component.extend({ + classNameBindings: ['isUrgent'], + isUrgent: true }); ``` diff --git a/source/object-model/enumerables.md b/source/object-model/enumerables.md index 324667a01..19159a98c 100644 --- a/source/object-model/enumerables.md +++ b/source/object-model/enumerables.md @@ -1,5 +1,3 @@ -## Enumerables - In Ember.js, an Enumerable is any object that contains a number of child objects, and which allows you to work with those children using the [Ember.Enumerable](http://emberjs.com/api/classes/Ember.Enumerable.html) API. The most common @@ -16,51 +14,37 @@ possible. This minimizes incompatibility with other libraries, and allows Ember.js to use the native browser implementations in arrays where available. -For instance, all Enumerables support the standard `forEach` method: - -```javascript -[1,2,3].forEach(function(item) { - console.log(item); -}); - -//=> 1 -//=> 2 -//=> 3 -``` - -In general, Enumerable methods, like `forEach`, take an optional second -parameter, which will become the value of `this` in the callback -function: - -```javascript -var array = [1,2,3]; - -array.forEach(function(item) { - console.log(item, this.indexOf(item)); -}, array) - -//=> 1 0 -//=> 2 1 -//=> 3 2 -``` - -### Enumerables in Ember.js - -Usually, objects that represent lists implement the Enumerable interface. Some examples: - - * **Array** - Ember extends the native JavaScript `Array` with the - Enumerable interface (unless you [disable prototype - extensions.](../../configuring-ember/disabling-prototype-extensions)) - * **Ember.Set** - A data structure that can efficiently answer whether it - includes an object. - -### API Overview - -In this guide, we'll explore some of the most common Enumerable +## Use of Observable Methods + +In order for Ember to observe when you make a change to an enumerable, you need +to use special methods that Ember.Enumerable provides. For example, if you add +an element to an array using the standard JavaScript method `push`, Ember will +not be able to observe the change, but if you use the Enumerable method +`pushObject`, the change will propagate throughout your application. + +Here is a list of standard JavaScript array methods and their observable +Enumerable equivalents: + + + + + + + + + + + + +
Standard MethodObservable Equivalent
poppopObject
pushpushObject
reversereverseObjects
shiftshiftObject
unshiftunshiftObject
+ +## API Overview + +In the rest of this guide, we'll explore some of the most common Enumerable conveniences. For the full list, please see the [Ember.Enumerable API reference documentation.](http://emberjs.com/api/classes/Ember.Enumerable.html) -#### Iterating Over an Enumerable +### Iterating Over an Enumerable To enumerate all the values of an enumerable object, use the `forEach` method: @@ -76,25 +60,7 @@ food.forEach(function(item, index) { // Menu Item 3: Adobo Chicken ``` -#### Making an Array Copy - -You can make a native array copy of any object that implements -`Ember.Enumerable` by calling the `toArray()` method: - -```javascript -var states = Ember.Set.create(); - -states.add("Hawaii"); -states.add("California") - -states.toArray() -//=> ["Hawaii", "California"] -``` - -Note that in many enumerables, such as the `Ember.Set` used in this -example, the order of the resulting array is not guaranteed. - -#### First and Last Objects +### First and Last Objects All Enumerables expose `firstObject` and `lastObject` properties that you can bind to. @@ -111,7 +77,7 @@ animals.get('lastObject'); //=> "peacock" ``` -#### Map +### Map You can easily transform each item in an enumerable using the `map()` method, which creates a new array with results of calling a @@ -145,7 +111,7 @@ states.mapBy('capital'); //=> ["Honolulu", "Sacramento"] ``` -#### Filtering +### Filtering Another common task to perform on an Enumerable is to take the Enumerable as input, and return an Array after filtering it based on @@ -185,7 +151,7 @@ todos.filterBy('isDone', true); If you want to return just the first matched value, rather than an Array containing all of the matched values, you can use `find` and `findBy`, which work just like `filter` and `filterBy`, but return only one item. -#### Aggregate Information (All or Any) +### Aggregate Information (All or Any) If you want to find out whether every item in an Enumerable matches some condition, you can use the `every` method: @@ -223,4 +189,3 @@ Just like the filtering methods, the `every` and `some` methods have analogous ` people.isEvery('isHappy', true) // false people.isAny('isHappy', true) // true ``` - diff --git a/source/object-model/index.md b/source/object-model/index.md new file mode 100644 index 000000000..2fe15bb1f --- /dev/null +++ b/source/object-model/index.md @@ -0,0 +1,16 @@ +You'll soon notice that standard JavaScript objects aren't used widely in Ember, +except as key-value pairs (often referred to as _hashes_). This is because +JavaScript objects don't support the ability to observe when an object changes, +which Ember needs to update data throughout an application. +Ember's object model builds on standard JavaScript objects to enable this +functionality, as well as bring several features like mixins and initialization +to make working with them a more pleasant experience. Although these features +aren't available in standard JavaScript, many of them are designed to align with +proposed additions to the ECMAScript standard. + +In addition to bringing its own object model, Ember also extends the built-in +JavaScript `Array` prototype with its Enumerable interface to enable it to +observe changes and provide more features. + +Finally, Ember extends the `String` prototype with a few [formatting and +localization methods](http://emberjs.com/api/classes/Ember.String.html). diff --git a/source/object-model/observers.md b/source/object-model/observers.md index 3a46c31d5..f7031f5a3 100644 --- a/source/object-model/observers.md +++ b/source/object-model/observers.md @@ -1,4 +1,13 @@ Ember supports observing any property, including computed properties. + +Observers should contain behavior that reacts to changes in another property. +Observers are especially useful when you need to perform some behavior after a +binding has finished synchronizing. + +Observers are often over-used by new Ember developers. Observers are used +heavily within the Ember framework itself, but for most problems Ember app +developers face, computed properties are the appropriate solution. + You can set up an observer on an object by using `Ember.observer`: ```javascript diff --git a/source/object-model/what-do-i-use-when.md b/source/object-model/what-do-i-use-when.md deleted file mode 100644 index 41d43fad3..000000000 --- a/source/object-model/what-do-i-use-when.md +++ /dev/null @@ -1,21 +0,0 @@ -Sometimes new users are confused about when to use computed properties, -bindings and observers. Here are some guidelines to help: - -1. Use *computed properties* to build a new property by synthesizing other -properties. Computed properties should not contain application behavior, and -should generally not cause any side-effects when called. Except in rare cases, -multiple calls to the same computed property should always return the same -value (unless the properties it depends on have changed, of course.) - -2. *Observers* should contain behavior that reacts to changes in another -property. Observers are especially useful when you need to perform some -behavior after a binding has finished synchronizing. - -3. *Bindings* are most often used to ensure objects in two different layers -are always in sync. For example, you bind your views to your controller using -Handlebars. - -### More Resources -Stefan Penner at Yahoo discusses when to use observers and when to use computed properties: -- [The observer tip-jar - Stefan Penner Silicon Valley Ember.js meetup Jun 15, 2015](https://www.youtube.com/watch?v=7PUX27RKCq0) -