Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

docs(hier-dep-inj): fix comp name, spelling in field name, copyedits #3335

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import { HeroTaxReturnService } from './hero-tax-return.service';
export class HeroTaxReturnComponent {
message = '';
@Output() close = new EventEmitter<void>();
@Input()

get taxReturn(): HeroTaxReturn {
return this.heroTaxReturnService.taxReturn;
}
@Input()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you move this here? I realize it is technically true that the @Input applies to the setter but does it looks awful and it doesn't change Angular's behavior, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a matter of style, we should encourage readers to associate @Input with setters. This way, documentation and refactoring tools, for example, will attribute the decorator to the proper class member.

Right, Angular's behavior isn't affected (though IMHO it might be incidental behavior that it happens to work when attached to the getter).

If you feel strongly about it, I can undo it. Let me know.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel strongly about it ... yet.

If we really believe that @Input should adorn the setter, we should find a place in the docs to say that and say why. If you have a moment to look for that place and propose language for it, I'd be grateful.

That would be a separate PR. I'm merging this one.

set taxReturn (htr: HeroTaxReturn) {
this.heroTaxReturnService.taxReturn = htr;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div>
<h3>Villains</h3>
<ul>
<li *ngFor="let villain of villaines | async">{{villain.name}}</li>
<li *ngFor="let villain of villains | async">{{villain.name}}</li>
</ul>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { Villain, VillainsService } from './villains.service';
})
// #enddocregion metadata
export class VillainsListComponent {
villaines: Observable<Villain[]>;
villains: Observable<Villain[]>;

constructor(private villainesService: VillainsService) {
this.villaines = villainesService.getVillains();
constructor(private villainsService: VillainsService) {
this.villains = villainsService.getVillains();
}
}
23 changes: 14 additions & 9 deletions public/docs/ts/latest/guide/hierarchical-dependency-injection.jade
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ figure.image-display
:marked
You can cap the bubbling. An intermediate component can declare that it is the "host" component.
The hunt for providers will climb no higher than the injector for that host component.
This a topic for another day.
This is a topic for another day.

:marked
### 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 don't *have* to re-register providers. You shouldn't do so unless you have a good reason.
But you *can*.
Expand All @@ -77,7 +78,6 @@ figure.image-display

The ability to configure one or more providers at different levels opens up interesting and useful possibilities.

:marked
### Scenario: service isolation

Architectural reasons may lead you to restrict access to a service to the application domain where it belongs.
Expand All @@ -93,9 +93,10 @@ figure.image-display

Instead, provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this:

+makeExample('hierarchical-dependency-injection/ts/src/app/villains-list.component.ts', 'metadata','src/app/villains-list.component.ts (metadata)')(format='.')
+makeExcerpt('src/app/villains-list.component.ts (metadata)')

:marked
By providing `VillainsService` in the `VillainsListComponent` metadata &mdash; and nowhere else &mdash;,
By providing `VillainsService` in the `VillainsListComponent` metadata and nowhere else,
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.

Expand All @@ -120,20 +121,23 @@ figure.image-display

figure.image-display
img(src="/resources/images/devguide/dependency-injection/hid-heroes-anim.gif" width="400" alt="Heroes in action")

:marked
One might suppose that the `TaxReturnComponent` 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.
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.

Here is the `HeroTaxReturnService`.
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.
+makeExample('hierarchical-dependency-injection/ts/src/app/hero-tax-return.service.ts', '', 'src/app/hero-tax-return.service.ts')

+makeExample('src/app/hero-tax-return.service.ts')

:marked
Here is the `HeroTaxReturnComponent` that makes use of it.
+makeExample('hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.ts', null, 'src/app/hero-tax-return.component.ts')

+makeExample('src/app/hero-tax-return.component.ts')

:marked
The _tax-return-to-edit_ arrives via the input property which is implemented with getters and setters.
Expand All @@ -148,7 +152,8 @@ figure.image-display

Look closely at the metadata for the `HeroTaxReturnComponent`. Notice the `providers` property.

+makeExample('hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.ts', 'providers')
+makeExcerpt('src/app/hero-tax-return.component.ts', 'providers', '')

:marked
The `HeroTaxReturnComponent` has its own provider of the `HeroTaxReturnService`.
Recall that every component _instance_ has its own injector.
Expand Down Expand Up @@ -194,7 +199,7 @@ figure.image-display
:marked
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>
:marked

//- ## Advanced Dependency Injection in Angular
//- Restrict Dependency Lookups
//- [TODO] (@Host) This has been postponed for now until we come up with a decent use case
Expand Down