docs(hierarchical-di): copy edits (#3354)
This commit is contained in:
parent
66562c8710
commit
8d88107004
@ -44,7 +44,7 @@ figure.image-display
|
|||||||
img(src="/resources/images/devguide/dependency-injection/component-hierarchy.png" alt="injector tree" width="600")
|
img(src="/resources/images/devguide/dependency-injection/component-hierarchy.png" alt="injector tree" width="600")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
### Injector bubbling
|
### Injector bubbling
|
||||||
|
|
||||||
When a component requests a dependency, Angular tries to satisfy that dependency with a provider registered in that component's own injector.
|
When a component requests a dependency, Angular tries to satisfy that dependency with a provider registered in that component's own injector.
|
||||||
If the component's injector lacks the provider, it passes the request up to its parent component's injector.
|
If the component's injector lacks the provider, it passes the request up to its parent component's injector.
|
||||||
@ -62,14 +62,14 @@ figure.image-display
|
|||||||
### Re-providing a service at different levels
|
### Re-providing a service at different levels
|
||||||
|
|
||||||
You can re-register a provider for a particular dependency token at multiple levels of the injector tree.
|
You can re-register a provider for a particular dependency token at multiple levels of the injector tree.
|
||||||
You don't *have* to re-register providers. You shouldn't do so unless you have a good reason.
|
You don't *have* to re-register providers. You shouldn't do so unless you have a good reason.
|
||||||
But you *can*.
|
But you *can*.
|
||||||
|
|
||||||
As the resolution logic works upwards, the first provider encountered wins.
|
As the resolution logic works upwards, the first provider encountered wins.
|
||||||
Thus, a provider in an intermediate injector intercepts a request for a service from something lower in the tree.
|
Thus, a provider in an intermediate injector intercepts a request for a service from something lower in the tree.
|
||||||
It effectively "reconfigures" and "shadows" a provider at a higher level in the tree.
|
It effectively "reconfigures" and "shadows" a provider at a higher level in the tree.
|
||||||
|
|
||||||
If you only specify providers at the top level (typically the root `AppModule`), the tree of injectors appears to be flat.
|
If you only specify providers at the top level (typically the root `AppModule`), the tree of injectors appears to be flat.
|
||||||
All requests bubble up to the root <span if-docs="ts"><code>NgModule</code></span> injector that you configured with the `!{_bootstrapModule}` method.
|
All requests bubble up to the root <span if-docs="ts"><code>NgModule</code></span> injector that you configured with the `!{_bootstrapModule}` method.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
@ -85,11 +85,11 @@ figure.image-display
|
|||||||
The guide sample includes a `VillainsListComponent` that displays a list of villains.
|
The guide sample includes a `VillainsListComponent` that displays a list of villains.
|
||||||
It gets those villains from a `VillainsService`.
|
It gets those villains from a `VillainsService`.
|
||||||
|
|
||||||
While you could provide `VillainsService` in the root `AppModule` (that's where you'll find the `HeroesService`),
|
While you _could_ provide `VillainsService` in the root `AppModule` (that's where you'll find the `HeroesService`),
|
||||||
that would make the `VillainsService` available everywhere in the application, including the _Hero_ workflows.
|
that would make the `VillainsService` available everywhere in the application, including the _Hero_ workflows.
|
||||||
|
|
||||||
If you later modify the `VillainsService`, you could break something in a hero component somewhere.
|
If you later modified the `VillainsService`, you could break something in a hero component somewhere.
|
||||||
That's not supposed to happen but the way you've provided the service creates that risk.
|
That's not supposed to happen but providing the service in the root `AppModule` creates that risk.
|
||||||
|
|
||||||
Instead, provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:
|
Instead, provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:
|
||||||
|
|
||||||
@ -100,37 +100,37 @@ figure.image-display
|
|||||||
the service becomes available only in the `VillainsListComponent` and its sub-component tree.
|
the service becomes available only in the `VillainsListComponent` and its sub-component tree.
|
||||||
It's still a singleton, but it's a singleton that exist solely in the _villain_ domain.
|
It's still a singleton, but it's a singleton that exist solely in the _villain_ domain.
|
||||||
|
|
||||||
You are confident that a hero component can't access it. You've reduced your exposure to error.
|
Now you know that a hero component can't access it. You've reduced your exposure to error.
|
||||||
|
|
||||||
### Scenario: multiple edit sessions
|
### Scenario: multiple edit sessions
|
||||||
|
|
||||||
Many applications allow users to work on several open tasks at the same time.
|
Many applications allow users to work on several open tasks at the same time.
|
||||||
For example, in a tax preparation application, the preparer could be working several tax returns,
|
For example, in a tax preparation application, the preparer could be working on several tax returns,
|
||||||
switching from one to the other throughout the day.
|
switching from one to the other throughout the day.
|
||||||
|
|
||||||
This guide demonstrates that scenario with an example in the Tour of Heroes theme.
|
This guide demonstrates that scenario with an example in the Tour of Heroes theme.
|
||||||
Imagine an outer `HeroListComponent` that displays a list of super heroes.
|
Imagine an outer `HeroListComponent` that displays a list of super heroes.
|
||||||
|
|
||||||
To open a hero's tax return, the preparer clicks on a hero name, which opens a component for editing that return.
|
To open a hero's tax return, the preparer clicks on a hero name, which opens a component for editing that return.
|
||||||
Each selected hero tax return opens in its own component and multiple returns can be open at the same time.
|
Each selected hero tax return opens in its own component and multiple returns can be open at the same time.
|
||||||
|
|
||||||
Each tax return component
|
Each tax return component has the following characteristics:
|
||||||
* is its own tax return editing session.
|
* Is its own tax return editing session.
|
||||||
* can change a tax return without affecting a return in another component.
|
* Can change a tax return without affecting a return in another component.
|
||||||
* has the ability to save the changes to its tax return or cancel them.
|
* Has the ability to save the changes to its tax return or cancel them.
|
||||||
|
|
||||||
figure.image-display
|
figure.image-display
|
||||||
img(src="/resources/images/devguide/dependency-injection/hid-heroes-anim.gif" width="400" alt="Heroes in action")
|
img(src="/resources/images/devguide/dependency-injection/hid-heroes-anim.gif" width="400" alt="Heroes in action")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
One might suppose that the `HeroTaxReturnComponent` has logic to manage and restore changes.
|
One might suppose that the `HeroTaxReturnComponent` has logic to manage and restore changes.
|
||||||
That would be a pretty easy task for a simple hero tax return.
|
That would be a pretty easy task for a simple hero tax return.
|
||||||
In the real world, with a rich tax return data model, the change management would be tricky.
|
In the real world, with a rich tax return data model, the change management would be tricky.
|
||||||
You might delegate that management to a helper service, as this example does.
|
You might delegate that management to a helper service, as this example does.
|
||||||
|
|
||||||
Here is the `HeroTaxReturnService`.
|
Here is the `HeroTaxReturnService`.
|
||||||
It caches a single `HeroTaxReturn`, tracks changes to that return, and can save or restore it.
|
It caches a single `HeroTaxReturn`, tracks changes to that return, and can save or restore it.
|
||||||
It also delegates to the application-wide, singleton `HeroService`, which it gets by injection.
|
It also delegates to the application-wide singleton `HeroService`, which it gets by injection.
|
||||||
|
|
||||||
+makeExample('src/app/hero-tax-return.service.ts')
|
+makeExample('src/app/hero-tax-return.service.ts')
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ figure.image-display
|
|||||||
The component also asks the service to save and restore this tax return.
|
The component also asks the service to save and restore this tax return.
|
||||||
|
|
||||||
There'd be big trouble if _this_ service were an application-wide singleton.
|
There'd be big trouble if _this_ service were an application-wide singleton.
|
||||||
Every component would share the same service instance.
|
Every component would share the same service instance.
|
||||||
Each component would overwrite the tax return that belonged to another hero.
|
Each component would overwrite the tax return that belonged to another hero.
|
||||||
What a mess!
|
What a mess!
|
||||||
|
|
||||||
@ -155,15 +155,15 @@ figure.image-display
|
|||||||
+makeExcerpt('src/app/hero-tax-return.component.ts', 'providers', '')
|
+makeExcerpt('src/app/hero-tax-return.component.ts', 'providers', '')
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
The `HeroTaxReturnComponent` has its own provider of the `HeroTaxReturnService`.
|
The `HeroTaxReturnComponent` has its own provider of the `HeroTaxReturnService`.
|
||||||
Recall that every component _instance_ has its own injector.
|
Recall that every component _instance_ has its own injector.
|
||||||
Providing the service at the component level ensures that _every_ instance of the component gets its own, private instance of the service.
|
Providing the service at the component level ensures that _every_ instance of the component gets its own, private instance of the service.
|
||||||
No tax return overwriting. No mess.
|
No tax return overwriting. No mess.
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
The rest of the scenario code relies on other Angular features and techniques that you can learn about elsewhere in the documentation.
|
The rest of the scenario code relies on other Angular features and techniques that you can learn about elsewhere in the documentation.
|
||||||
You can review it and download it from the <live-example></live-example>
|
You can review it and download it from the <live-example></live-example>.
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
### Scenario: specialized providers
|
### Scenario: specialized providers
|
||||||
@ -172,7 +172,7 @@ figure.image-display
|
|||||||
deeper in the component tree.
|
deeper in the component tree.
|
||||||
|
|
||||||
Consider again the Car example from the [Dependency Injection](./dependency-injection.html) guide.
|
Consider again the Car example from the [Dependency Injection](./dependency-injection.html) guide.
|
||||||
Suppose you configured the root injector (marked as A) with _generic_ providers for
|
Suppose you configured the root injector (marked as A) with _generic_ providers for
|
||||||
`CarService`, `EngineService` and `TiresService`.
|
`CarService`, `EngineService` and `TiresService`.
|
||||||
|
|
||||||
You create a car component (A) that displays a car constructed from these three generic services.
|
You create a car component (A) that displays a car constructed from these three generic services.
|
||||||
@ -198,8 +198,7 @@ figure.image-display
|
|||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
The code for this _cars_ scenario is in the `car.components.ts` and `car.services.ts` files of the sample
|
The code for this _cars_ scenario is in the `car.components.ts` and `car.services.ts` files of the sample
|
||||||
which you can review and download from the <live-example></live-example>
|
which you can review and download from the <live-example></live-example>.
|
||||||
|
|
||||||
//- ## Advanced Dependency Injection in Angular
|
//- ## Advanced Dependency Injection in Angular
|
||||||
//- Restrict Dependency Lookups
|
//- Restrict Dependency Lookups
|
||||||
//- [TODO] (@Host) This has been postponed for now until we come up with a decent use case
|
//- [TODO] (@Host) This has been postponed for now until we come up with a decent use case
|
||||||
|
Loading…
x
Reference in New Issue
Block a user