{ "id": "tutorial/toh-pt3", "title": "Create a feature component", "contents": "\n\n\n
At the moment, the HeroesComponent
displays both the list of heroes and the selected hero's details.
Keeping all features in one component as the application grows will not be maintainable.\nYou'll want to split up large components into smaller sub-components, each focused on a specific task or workflow.
\nIn this page, you'll take the first step in that direction by moving the hero details into a separate, reusable HeroDetailComponent
.
The HeroesComponent
will only present the list of heroes.\nThe HeroDetailComponent
will present details of a selected hero.
For the sample application that this page describes, see the
HeroDetailComponent
linkUse the Angular CLI to generate a new component named hero-detail
.
The command scaffolds the following:
\nsrc/app/hero-detail
.Inside that directory four files are generated:
\nHeroDetailComponent
.HeroDetailComponent
class.The command also adds the HeroDetailComponent
as a declaration in the @NgModule
decorator of the src/app/app.module.ts
file.
Cut the HTML for the hero detail from the bottom of the HeroesComponent
template and paste it over the generated boilerplate in the HeroDetailComponent
template.
The pasted HTML refers to a selectedHero
.\nThe new HeroDetailComponent
can present any hero, not just a selected hero.\nSo replace \"selectedHero\" with \"hero\" everywhere in the template.
When you're done, the HeroDetailComponent
template should look like this:
@Input()
hero propertylinkThe HeroDetailComponent
template binds to the component's hero
property\nwhich is of type Hero
.
Open the HeroDetailComponent
class file and import the Hero
symbol.
The hero
property\nmust be an Input property,\nannotated with the @Input()
decorator,\nbecause the external HeroesComponent
will bind to it like this.
Amend the @angular/core
import statement to include the Input
symbol.
Add a hero
property, preceded by the @Input()
decorator.
That's the only change you should make to the HeroDetailComponent
class.\nThere are no more properties. There's no presentation logic.\nThis component only receives a hero object through its hero
property and displays it.
HeroDetailComponent
linkThe HeroesComponent
used to display the hero details on its own, before you removed that portion of the template.\nThis section guides you through delegating logic to the HeroDetailComponent
.
The two components will have a parent/child relationship.\nThe parent HeroesComponent
will control the child HeroDetailComponent
\nby sending it a new hero to display whenever\nthe user selects a hero from the list.
You won't change the HeroesComponent
class but you will change its template.
HeroesComponent
templatelinkThe HeroDetailComponent
selector is 'app-hero-detail'
.\nAdd an <app-hero-detail>
element near the bottom of the HeroesComponent
template, where the hero detail view used to be.
Bind the HeroesComponent.selectedHero
to the element's hero
property like this.
[hero]=\"selectedHero\"
is an Angular property binding.
It's a one way data binding from\nthe selectedHero
property of the HeroesComponent
to the hero
property of the target element, which maps to the hero
property of the HeroDetailComponent
.
Now when the user clicks a hero in the list, the selectedHero
changes.\nWhen the selectedHero
changes, the property binding updates hero
\nand the HeroDetailComponent
displays the new hero.
The revised HeroesComponent
template should look like this:
The browser refreshes and the application starts working again as it did before.
\nAs before, whenever a user clicks on a hero name,\nthe hero detail appears below the hero list.\nNow the HeroDetailComponent
is presenting those details instead of the HeroesComponent
.
Refactoring the original HeroesComponent
into two components yields benefits, both now and in the future:
You reduced the HeroesComponent
responsibilities.
You can evolve the HeroDetailComponent
into a rich hero editor\nwithout touching the parent HeroesComponent
.
You can evolve the HeroesComponent
without touching the hero detail view.
You can re-use the HeroDetailComponent
in the template of some future component.
Here are the code files discussed on this page.
\nHeroDetailComponent
.HeroesComponent
control over the child HeroDetailComponent
.@Input
decorator\nto make the hero
property available for binding\nby the external HeroesComponent
.