Skip to content
This repository was archived by the owner on May 26, 2019. It is now read-only.

QUEST | Convert code samples to RFC #176 imports #2004

Merged
merged 18 commits into from
Oct 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions data/spelling-exceptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ apache
api
apis
app's
ApplicationInstance
assistive
async
asynchronicity
Expand Down
7 changes: 2 additions & 5 deletions source/applications/applications-and-instances.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
Every Ember application is represented by a class that extends [`Ember.Application`][1].
Every Ember application is represented by a class that extends [`Application`](http://emberjs.com/api/classes/Application.html).
This class is used to declare and configure the many objects that make up your app.

As your application boots,
it creates an [`Ember.ApplicationInstance`][2] that is used to manage its stateful aspects.
it creates an [`ApplicationInstance`](http://emberjs.com/api/classes/ApplicationInstance.html) that is used to manage its stateful aspects.
This instance acts as the "owner" of objects instantiated for your app.

Essentially, the `Application` *defines your application*
while the `ApplicationInstance` *manages its state*.

[1]: http://emberjs.com/api/classes/Ember.Application.html
[2]: http://emberjs.com/api/classes/Ember.ApplicationInstance.html

This separation of concerns not only clarifies the architecture of your app,
it can also improve its efficiency.
This is particularly true when your app needs to be booted repeatedly during testing
Expand Down
62 changes: 27 additions & 35 deletions source/applications/dependency-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@ Ember applications utilize the [dependency injection](https://en.wikipedia.org/w
("DI") design pattern to declare and instantiate classes of objects and dependencies between them.
Applications and application instances each serve a role in Ember's DI implementation.

An [`Ember.Application`][1] serves as a "registry" for dependency declarations.
An [`Application`](http://emberjs.com/api/classes/Ember.Application.html) serves as a "registry" for dependency declarations.
Factories (i.e. classes) are registered with an application,
as well as rules about "injecting" dependencies that are applied when objects are instantiated.

An [`Ember.ApplicationInstance`][2] serves as the "owner" for objects that are instantiated from registered factories.
An [`ApplicationInstance`](http://emberjs.com/api/classes/Ember.ApplicationInstance.html) serves as the "owner" for objects that are instantiated from registered factories.
Application instances provide a means to "look up" (i.e. instantiate and / or retrieve) objects.

> _Note: Although an `Application` serves as the primary registry for an app,
each `ApplicationInstance` can also serve as a registry.
Instance-level registrations are useful for providing instance-level customizations,
such as A/B testing of a feature._

[1]: http://emberjs.com/api/classes/Ember.Application.html
[2]: http://emberjs.com/api/classes/Ember.ApplicationInstance.html

## Factory Registrations

A factory can represent any part of your application, like a _route_, _template_, or custom class.
Expand All @@ -39,10 +36,10 @@ or application instance initializers (with the former being much more common).
For example, an application initializer could register a `Logger` factory with the key `logger:main`:

```app/initializers/logger.js
import Ember from 'ember';
import EmberObject from "@ember/object";

export function initialize(application) {
let Logger = Ember.Object.extend({
let Logger = EmberObject.extend({
log(m) {
console.log(m);
}
Expand Down Expand Up @@ -95,10 +92,10 @@ register your factories as non-singletons using the `singleton: false` option.
In the following example, the `Message` class is registered as a non-singleton:

```app/initializers/notification.js
import Ember from 'ember';
import EmberObject from "@ember/object";

export function initialize(application) {
let Message = Ember.Object.extend({
let Message = EmberObject.extend({
text: ''
});

Expand All @@ -118,10 +115,10 @@ Once a factory is registered, it can be "injected" where it is needed.
Factories can be injected into whole "types" of factories with *type injections*. For example:

```app/initializers/logger.js
import Ember from 'ember';
import EmberObject from "@ember/object";

export function initialize(application) {
let Logger = Ember.Object.extend({
let Logger = EmberObject.extend({
log(m) {
console.log(m);
}
Expand All @@ -144,9 +141,9 @@ The value of `logger` will come from the factory named `logger:main`.
Routes in this example application can now access the injected logger:

```app/routes/index.js
import Ember from 'ember';
import Route from "@ember/routing/route";

export default Ember.Route.extend({
export default Route.extend({
activate() {
// The logger property is injected into all routes
this.get('logger').log('Entered the index route!');
Expand All @@ -167,35 +164,37 @@ This includes all of Ember's major framework classes, such as components, helper

### Ad Hoc Injections

Dependency injections can also be declared directly on Ember classes using `Ember.inject`.
Currently, `Ember.inject` supports injecting controllers (via `Ember.inject.controller`)
and services (via `Ember.inject.service`).
Dependency injections can also be declared directly on Ember classes using `inject`.
Currently, `inject` supports injecting controllers (via `import { inject } from '@ember/controller';`)
and services (via `import { inject } from '@ember/service';`).

The following code injects the `shopping-cart` service on the `cart-contents` component as the property `cart`:

```app/components/cart-contents.js
import Ember from 'ember';
import Component from '@ember/component';
import { inject as service } from "@ember/service";

export default Ember.Component.extend({
cart: Ember.inject.service('shopping-cart')
export default Component.extend({
cart: service('shopping-cart')
});
```

If you'd like to inject a service with the same name as the property,
simply leave off the service name (the dasherized version of the name will be used):

```app/components/cart-contents.js
import Ember from 'ember';
import Component from '@ember/component';
import { inject as service } from "@ember/service";

export default Ember.Component.extend({
shoppingCart: Ember.inject.service()
export default Component.extend({
shoppingCart: service()
});
```

## Factory Instance Lookups

To fetch an instantiated factory from the running application you can call the
[`lookup`][3] method on an application instance. This method takes a string
[`lookup`](http://emberjs.com/api/classes/Ember.ApplicationInstance.html#method_lookup) method on an application instance. This method takes a string
to identify a factory and returns the appropriate object.

```javascript
Expand Down Expand Up @@ -226,21 +225,18 @@ export default {

### Getting an Application Instance from a Factory Instance

[`Ember.getOwner`][4] will retrieve the application instance that "owns" an
[`Ember.getOwner`](http://emberjs.com/api/#method_getOwner) will retrieve the application instance that "owns" an
object. This means that framework objects like components, helpers, and routes
can use [`Ember.getOwner`][4] to perform lookups through their application
can use [`Ember.getOwner`](http://emberjs.com/api/#method_getOwner) to perform lookups through their application
instance at runtime.

For example, this component plays songs with different audio services based
on a song's `audioType`.

```app/components/play-audio.js
import Ember from 'ember';
const {
Component,
computed,
getOwner
} = Ember;
import Component from '@ember/component';
import { computed } from "@ember/object";
import { getOwner } from "@ember/application";

// Usage:
//
Expand All @@ -259,7 +255,3 @@ export default Component.extend({
}
});
```

[3]: http://emberjs.com/api/classes/Ember.ApplicationInstance.html#method_lookup
[4]: http://emberjs.com/api/#method_getOwner

17 changes: 9 additions & 8 deletions source/applications/run-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,15 @@ Essentially, batching similar work allows for better pipelining, and further opt
Let's look at a similar example that is optimized in Ember, starting with a `User` object:

```javascript
let User = Ember.Object.extend({
import EmberObject, {
computed
} from '@ember/object';

let User = EmberObject.extend({
firstName: null,
lastName: null,
fullName: Ember.computed('firstName', 'lastName', function() {

fullName: computed('firstName', 'lastName', function() {
return `${this.get('firstName')} ${this.get('lastName')}`;
})
});
Expand Down Expand Up @@ -193,14 +198,10 @@ $('a').click(() => {
});
```

The run loop API calls that _schedule_ work, i.e. [`run.schedule`][1], [`run.scheduleOnce`][2],
[`run.once`][3] have the property that they will approximate a run loop for you if one does not already exist.
The run loop API calls that _schedule_ work, i.e. [`run.schedule`](http://emberjs.com/api/classes/Ember.run.html#method_schedule), [`run.scheduleOnce`](http://emberjs.com/api/classes/Ember.run.html#method_scheduleOnce),
[`run.once`](http://emberjs.com/api/classes/Ember.run.html#method_once) have the property that they will approximate a run loop for you if one does not already exist.
These automatically created run loops we call _autoruns_.

[1]: http://emberjs.com/api/classes/Ember.run.html#method_schedule
[2]: http://emberjs.com/api/classes/Ember.run.html#method_scheduleOnce
[3]: http://emberjs.com/api/classes/Ember.run.html#method_once

Here is some pseudocode to describe what happens using the example above:

```javascript
Expand Down
49 changes: 25 additions & 24 deletions source/applications/services.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
An [`Ember.Service`][1] is an Ember object that lives for the duration of the application, and can be made available in different parts of your application.

[1]: http://emberjs.com/api/classes/Ember.Service.html
An [`Service`](http://emberjs.com/api/classes/Ember.Service.html) is an Ember object that lives for the duration of the application, and can be made available in different parts of your application.

Services are useful for features that require shared state or persistent connections. Example uses of services might
include:
Expand All @@ -22,24 +20,22 @@ For example, the following command will create the `ShoppingCart` service:
ember generate service shopping-cart
```

Services must extend the [`Ember.Service`][1] base class:

[1]: http://emberjs.com/api/classes/Ember.Service.html
Services must extend the [`Service`](http://emberjs.com/api/classes/Ember.Service.html) base class:

```app/services/shopping-cart.js
import Ember from 'ember';
import Service from '@ember/service';

export default Ember.Service.extend({
export default Service.extend({
});
```

Like any Ember object, a service is initialized and can have properties and methods of its own.
Below, the shopping cart service manages an items array that represents the items currently in the shopping cart.

```app/services/shopping-cart.js
import Ember from 'ember';
import Service from '@ember/service';

export default Ember.Service.extend({
export default Service.extend({
items: null,

init() {
Expand All @@ -64,29 +60,31 @@ export default Ember.Service.extend({
### Accessing Services

To access a service,
you can inject it in any container-resolved object such as a component or another service using the `Ember.inject.service` function.
you can inject it in any container-resolved object such as a component or another service using the `inject` function from the `@ember/service` module.
There are two ways to use this function.
You can either invoke it with no arguments, or you can pass it the registered name of the service.
When no arguments are passed, the service is loaded based on the name of the variable key.
You can load the shopping cart service with no arguments like below.

```app/components/cart-contents.js
import Ember from 'ember';
import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default Ember.Component.extend({
export default Component.extend({
//will load the service in file /app/services/shopping-cart.js
shoppingCart: Ember.inject.service()
shoppingCart: service()
});
```

Another way to inject a service is to provide the name of the service as the argument.

```app/components/cart-contents.js
import Ember from 'ember';
import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default Ember.Component.extend({
export default Component.extend({
//will load the service in file /app/services/shopping-cart.js
cart: Ember.inject.service('shopping-cart')
cart: service('shopping-cart')
});
```

Expand All @@ -97,12 +95,14 @@ Since normal injection will throw an error if the service doesn't exist,
you must look up the service using Ember's [`getOwner`](https://emberjs.com/api/classes/Ember.html#method_getOwner) instead.

```app/components/cart-contents.js
import Ember from 'ember';
import Component from '@ember/component';
import { computed } from "@ember/object";
import { getOwner } from "@ember/application";

export default Ember.Component.extend({
export default Component.extend({
//will load the service in file /app/services/shopping-cart.js
cart: Ember.computed(function() {
return Ember.getOwner(this).lookup('service:shopping-cart');
cart: computed(function() {
return getOwner(this).lookup('service:shopping-cart');
})
});
```
Expand All @@ -116,10 +116,11 @@ Below we add a remove action to the `cart-contents` component.
Notice that below we access the `cart` service with a call to`this.get`.

```app/components/cart-contents.js
import Ember from 'ember';
import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default Ember.Component.extend({
cart: Ember.inject.service('shopping-cart'),
export default Component.extend({
cart: service('shopping-cart'),

actions: {
remove(item) {
Expand Down
Loading