(single responsibility principle)
Our template become more and more extensive, it has more details in it. It shows all heroes
and in the same moment it presents details for one hero
, too.
Such component is difficult to maintain as with more features it will become more complicated.
In this chapter, we will separate this component to be easier to maintain. The list of heroes will stay in this component. For the part that presents hero's details, we will create a new component named HeroDetailComponent
.
We are already familiar with ng generate component
command.
Into the terminal
write the following command:
ng generate component hero-detail
It generates the new component and automatically adds reference of the HeroDetailComponent
to the AppModule
.
We will move the details of the heroes into the new component template.
Here it is possible to reuse this component without such selected hero. We will replace the "selectedHero"
with "hero"
.
Open the hero-detail.component.html
file and type the changes. It should look like this:
<div *ngIf="hero">
<h2>{{ hero.name | uppercase }} Details</h2>
<div>
<span>id: </span>{{hero.id}}</div>
<div>
<label>name:
<jqxInput [(ngModel)]="hero.name" [placeHolder]="'hero name'"></jqxInput>
</label>
</div>
</div>
The hero
property that we include in our template will be of type Hero
. This means we should import the Hero
class.
import { Hero } from '../hero';
Now we need to add the Input directive to that component. With the @Input()
decorator we will get the external data and we need to include it into the imported Component
and OnInit
decorators:
import { Component, OnInit, Input } from '@angular/core';
The HeroesComponent
template will translate data by the hero
property, like this:
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
The HeroesComponent's template now looks like this:
<h2>My Heroes</h2>
<jqxGrid #grid
(onRowclick)="rowdetails($event)"
[autoheight]="true"
[theme]="'material'">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr *ngFor="let hero of heroes">
<td>
{{hero.id}}</td>
<td>
{{hero.name}}</td>
</tr>
</jqxGrid>
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
The syntax to determine a property that will be used in the template is @Input()
and after that the name of the property hero
. In our case:
@Input() hero: Hero;
That is all we do in this component - get the data (hero
property) and represent it on the display.
With the <app-hero-detail [hero]="selectedHero"></app-hero-detail>
we simplify the structure in the HeroesComponent
.
After these changes, when you save all files, it will reflect in our example and it should work normally as before.
Everything looks like before but now our components have the following benefits:
HeroesComponent
and simplified it as a result of this.HeroDetailComponent
into a new editor without touching the HeroesComponent
.HeroesComponent
do not need to care about these changes into the "hero details" view.HeroDetailComponent
into another place where you want.HeroDetailComponent
.HeroesComponent
over its child HeroDetailComponent
.HeroesComponent
into the hero
property of the HeroDetailComponent
by using the @Input decorator.