diff --git a/aio/content/examples/providers-viewproviders/src/app/app.component.ts b/aio/content/examples/providers-viewproviders/src/app/app.component.ts index b656bdd94c..1c9e56abef 100755 --- a/aio/content/examples/providers-viewproviders/src/app/app.component.ts +++ b/aio/content/examples/providers-viewproviders/src/app/app.component.ts @@ -13,3 +13,19 @@ export class AppComponent { constructor(public flower: FlowerService, public animal: AnimalService) {} } // #enddocregion inject-animal-service + +// When using @Host() together with @SkipSelf() in +// child.component.ts for the AnimalService, add the +// following viewProviders array to the @Component metadata: + +// viewProviders: [{ provide: AnimalService, useValue: { emoji: '🦔' } }] + +// So, the entire @ChildComponent() decorator and its +// metadata should be as follows: + +// @Component({ +// selector: 'app-root', +// templateUrl: './app.component.html', +// styleUrls: [ './app.component.css' ], +// viewProviders: [{ provide: AnimalService, useValue: { emoji: '🦔' } }] +// }) diff --git a/aio/content/guide/hierarchical-dependency-injection.md b/aio/content/guide/hierarchical-dependency-injection.md index 1506ca8567..15d3d1e5ed 100644 --- a/aio/content/guide/hierarchical-dependency-injection.md +++ b/aio/content/guide/hierarchical-dependency-injection.md @@ -1,9 +1,9 @@ # Hierarchical injectors Injectors in Angular have rules that you can leverage to -achieve the desired visibility in your apps. +achieve the desired visibility of injectables in your apps. By understanding these rules, you can determine in which -provider you should declare a provider. +NgModule or component you should declare a provider. ## Two injector hierarchies @@ -146,14 +146,6 @@ in the `providers` list of the `AppModule`. Angular creates `ElementInjector`s implicitly for each DOM element. -
- -**Note:** Specifically, `ElementInjector` is more nunaced -in that they are created _sparsely_. For a mental model -though, assume that each DOM element gets an `ElementInjector`. - -
- Providing a service in the `@Component()` decorator using its `providers` or `viewProviders` property configures an `ElementInjector`. @@ -171,10 +163,10 @@ export class TestComponent
-**Note:** `ModuleInjector` is not a parent of `ElementInjector`. -In theory, each element can have a different `ModuleInjector`. -Think of it as `ModuleInjector` is plan-b when the -`ElementInjector` hierarchy can't resolve it. +**Note:** Please see the +[resolution rules](guide/hierarchical-dependency-injection#resolution-rules) +section to understand the relationship between the `ModuleInjector` tree and +the `ElementInjector` tree.
@@ -546,7 +538,7 @@ In the example case, the constraints are: - The ending location just happens to be the same as the component itself, because it is the topmost component in this application. -2. The `MyAppModule` acts as the fallback injector when the +2. The `AppModule` acts as the fallback injector when the injection token can't be found in the `ElementInjector`s. ### Using the `providers` array @@ -570,7 +562,7 @@ The next step is to add a binding to the `ChildComponent` template. To render the new values, add `` to the bottom of -the`MyAppComponent` template so the view also displays the sunflower: +the`AppComponent` template so the view also displays the sunflower: ``` Child Component @@ -580,7 +572,7 @@ Emoji from FlowerService: 🌻 In the logical tree, this would be represented as follows: ``` -"🌺"> <#VIEW>

Emoji from FlowerService: {{flower.emoji}} (🌺)

@@ -656,7 +648,7 @@ it has a value of 🐶 (puppy). -Add bindings to the `ChildComponent` and the `MyAppComponent` templates. +Add bindings to the `ChildComponent` and the `AppComponent` templates. In the `ChildComponent` template, add the following binding: @@ -848,7 +840,7 @@ Emoji from FlowerService: 🌺 In a logical tree, this same idea might look like this: ``` -"🌺"> <#VIEW> @@ -871,7 +863,7 @@ because `@Host()` limits the upper bound of the search to the `<#VIEW>`. Here's the idea in the logical tree: ``` -"🌺"> <#VIEW> @@ -902,7 +894,7 @@ for the `AnimalService`, it never sees the 🐳 (whale). Just as in the `FlowerService` example, if you add `@SkipSelf()` to the constructor for the `AnimalService`, the injector won't -look in the current ``'s `ElementInjector` for the +look in the current ``'s `ElementInjector` for the `AnimalService`. ```typescript= @@ -914,7 +906,7 @@ export class ChildComponent { } ``` -Instead, the injector will begin at the `` +Instead, the injector will begin at the `` `ElementInjector`. Remember that the `` class provides the `AnimalService` in the `viewProviders` array with a value of 🐶 (puppy): @@ -931,7 +923,7 @@ with a value of 🐶 (puppy): The logical tree looks like this with `@SkipSelf()` in ``: ``` - "🐳")> <#VIEW> @@ -985,9 +977,21 @@ export class ChildComponent { ``` -However, if you use `@Host()` and `@SkipSelf()` for the `AnimalService` -as follows, you'll get 🐶 (puppy) because that's the value in the -``. Here are `@Host()` and `@SkipSelf()` in the `` +Add a `viewProviders` array with a third animal, 🦔 (hedgehog), to the +`app.component.ts` `@Component()` metadata: + +```typescript +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: [ './app.component.css' ], + viewProviders: [{ provide: AnimalService, useValue: { emoji: '🦔' } }] +}) +``` + +Next, add `@SkipSelf()` along with `@Host()` to the constructor for the +`Animal Service` in `child.component.ts`. Here are `@Host()` +and `@SkipSelf()` in the `` constructor : ```ts @@ -1007,15 +1011,16 @@ which is in the `providers` array, the result was `null` because `FlowerService` is visible in ``, not its `<#VIEW>`. However, the `AnimalService`, which is provided in the -`ParentComponent` `viewProviders` array, is visible. +`AppComponent` `viewProviders` array, is visible. The logical tree representation shows why this is: ```html -"🐳")> - <#VIEW> - + <#VIEW @Provide(AnimalService="🦔") + @Inject(AnimalService, @SkipSelf, @Host, @Optional)=>"🦔"> + <#VIEW @Provide(AnimalService="🐶") @Inject(AnimalService, @SkipSelf, @Host, @Optional)=>"🐶"> @@ -1030,8 +1035,8 @@ The logical tree representation shows why this is: the `AnimalService` at the ``, not the ``, where the request originates, and `@Host()` stops the search at the `` `<#VIEW>`. Since `AnimalService` is -provided via the `viewProviders` array, the injector finds 🐶 -(puppy) in the `<#VIEW>`. +provided via the `viewProviders` array, the injector finds 🦔 +(hedgehog) in the `<#VIEW>`. {@a component-injectors}