parent
6a62ed2245
commit
c7e2930f25
|
@ -12,16 +12,17 @@ import { HEROES } from '../mock-heroes';
|
|||
styleUrls: ['./heroes.component.css']
|
||||
})
|
||||
// #enddocregion metadata
|
||||
|
||||
// #docregion component
|
||||
export class HeroesComponent implements OnInit {
|
||||
|
||||
// #docregion heroes
|
||||
heroes = HEROES;
|
||||
// #enddocregion heroes
|
||||
|
||||
// #enddocregion component
|
||||
// #docregion on-select
|
||||
selectedHero: Hero;
|
||||
|
||||
// #enddocregion on-select
|
||||
// #enddocregion on-select
|
||||
|
||||
constructor() { }
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<!-- #docregion click -->
|
||||
<a *ngFor="let hero of heroes" class="col-1-4"
|
||||
routerLink="/detail/{{hero.id}}">
|
||||
<!-- #enddocregion click -->
|
||||
<div class="module hero">
|
||||
<h4>{{hero.name}}</h4>
|
||||
</div>
|
||||
</a>
|
||||
<!-- #enddocregion click -->
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// #docregion , init
|
||||
import { InMemoryDbService } from 'angular-in-memory-web-api';
|
||||
import { Hero } from './hero';
|
||||
|
||||
export class InMemoryDataService implements InMemoryDbService {
|
||||
createDb() {
|
||||
|
@ -17,4 +18,13 @@ export class InMemoryDataService implements InMemoryDbService {
|
|||
];
|
||||
return {heroes};
|
||||
}
|
||||
|
||||
// Overrides the genId method to ensure that a hero always has an id.
|
||||
// If the heroes array is empty,
|
||||
// the method below returns the initial number (11).
|
||||
// if the heroes array is not empty, the method below returns the highest
|
||||
// hero id + 1.
|
||||
genId(heroes: Hero[]): number {
|
||||
return heroes.length > 0 ? Math.max(...heroes.map(hero => hero.id)) + 1 : 11;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@ Open the `HeroesComponent` class file and import the mock `HEROES`.
|
|||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="import-heroes" title="src/app/heroes/heroes.component.ts (import HEROES)">
|
||||
</code-example>
|
||||
|
||||
Add a `heroes` property to the class that exposes these heroes for binding.
|
||||
In the same file (`HeroesComponent` class), define a component property called `heroes` to expose `HEROES` array for binding.
|
||||
|
||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="heroes">
|
||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="component">
|
||||
</code-example>
|
||||
|
||||
### List heroes with _*ngFor_
|
||||
|
@ -245,6 +245,7 @@ Here are the code files discussed on this page, including the `HeroesComponent`
|
|||
|
||||
<code-pane title="src/app/heroes/heroes.component.css" path="toh-pt2/src/app/heroes/heroes.component.css">
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Master/Detail Components
|
||||
|
||||
At the moment, the `HeroesComponent` displays both the list of heroes and the selected hero's details.
|
||||
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.
|
||||
You'll want to split up large components into smaller sub-components, each focused on a specific task or workflow.
|
||||
|
@ -18,7 +18,19 @@ Use the Angular CLI to generate a new component named `hero-detail`.
|
|||
ng generate component hero-detail
|
||||
</code-example>
|
||||
|
||||
The command scaffolds the `HeroDetailComponent` files and declares the component in `AppModule`.
|
||||
The command scaffolds the following:
|
||||
|
||||
* Creates a directory `src/app/hero-detail`.
|
||||
|
||||
Inside that directory four files are generated:
|
||||
|
||||
* A CSS file for the component styles.
|
||||
* An HTML file for the component template.
|
||||
* A TypeScript file with a component class named `HeroDetailComponent`.
|
||||
* A test file for the `HeroDetailComponent` class.
|
||||
|
||||
The command also adds the `HeroDetailComponent` as a declaration in the `@NgModule` decorator of the `src/app/app.module.ts` file.
|
||||
|
||||
|
||||
### Write the template
|
||||
|
||||
|
@ -26,7 +38,7 @@ Cut the HTML for the hero detail from the bottom of the `HeroesComponent` templa
|
|||
|
||||
The pasted HTML refers to a `selectedHero`.
|
||||
The new `HeroDetailComponent` can present _any_ hero, not just a selected hero.
|
||||
So replace "selectedHero" with "hero" everywhere in the template.
|
||||
So replace "selectedHero" with "hero" everywhere in the template.
|
||||
|
||||
When you're done, the `HeroDetailComponent` template should look like this:
|
||||
|
||||
|
@ -41,11 +53,11 @@ which is of type `Hero`.
|
|||
|
||||
Open the `HeroDetailComponent` class file and import the `Hero` symbol.
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts"
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts"
|
||||
region="import-hero" title="src/app/hero-detail/hero-detail.component.ts (import Hero)">
|
||||
</code-example>
|
||||
|
||||
The `hero` property
|
||||
The `hero` property
|
||||
[must be an _Input_ property](guide/template-syntax#inputs-outputs "Input and Output properties"),
|
||||
annotated with the `@Input()` decorator,
|
||||
because the _external_ `HeroesComponent` [will bind to it](#heroes-component-template) like this.
|
||||
|
@ -64,17 +76,17 @@ Add a `hero` property, preceded by the `@Input()` decorator.
|
|||
</code-example>
|
||||
|
||||
That's the only change you should make to the `HeroDetailComponent` class.
|
||||
There are no more properties. There's no presentation logic.
|
||||
There are no more properties. There's no presentation logic.
|
||||
This component simply receives a hero object through its `hero` property and displays it.
|
||||
|
||||
## Show the `HeroDetailComponent`
|
||||
|
||||
The `HeroesComponent` is still a master/detail view.
|
||||
The `HeroesComponent` is still a master/detail view.
|
||||
|
||||
It used to display the hero details on its own, before you cut that portion of the template. Now it will delegate to the `HeroDetailComponent`.
|
||||
|
||||
The two components will have a parent/child relationship.
|
||||
The parent `HeroesComponent` will control the child `HeroDetailComponent`
|
||||
The parent `HeroesComponent` will control the child `HeroDetailComponent`
|
||||
by sending it a new hero to display whenever
|
||||
the user selects a hero from the list.
|
||||
|
||||
|
@ -155,6 +167,6 @@ Here are the code files discussed on this page and your app should look like thi
|
|||
* You used a [property binding](guide/template-syntax#property-binding) to give the parent `HeroesComponent` control over the child `HeroDetailComponent`.
|
||||
|
||||
|
||||
* You used the [`@Input` decorator](guide/template-syntax#inputs-outputs)
|
||||
* You used the [`@Input` decorator](guide/template-syntax#inputs-outputs)
|
||||
to make the `hero` property available for binding
|
||||
by the external `HeroesComponent`.
|
||||
|
|
|
@ -66,7 +66,7 @@ which you will create in a moment.
|
|||
</code-example>
|
||||
|
||||
Add the `HttpClientInMemoryWebApiModule` to the `@NgModule.imports` array—
|
||||
_after importing the `HttpClient`_,
|
||||
_after importing the `HttpClientModule`_,
|
||||
—while configuring it with the `InMemoryDataService`.
|
||||
|
||||
<code-example
|
||||
|
@ -114,7 +114,9 @@ you'll wrap it in private `log` method.
|
|||
region="log" >
|
||||
</code-example>
|
||||
|
||||
Define the `heroesUrl` with the address of the heroes resource on the server.
|
||||
Define the `heroesUrl` of the form `:base/:collectionName` with the address of the heroes resource on the server.
|
||||
Here `base` is the resource to which requests are made,
|
||||
and `collectionName` is the heroes data object in the `in-memory-data-service.ts`.
|
||||
|
||||
<code-example
|
||||
path="toh-pt6/src/app/hero.service.ts"
|
||||
|
@ -242,8 +244,11 @@ Here is the final version of `getHeroes` with the `tap` that logs the operation.
|
|||
|
||||
### Get hero by id
|
||||
|
||||
Most web APIs support a _get by id_ request in the form `api/hero/:id`
|
||||
(such as `api/hero/11`).
|
||||
Most web APIs support a _get by id_ request in the form `:baseURL/:id`.
|
||||
|
||||
Here, the _base URL_ is the `heroesURL` defined in the [Heroes and HTTP](http://localhost:4800/tutorial/toh-pt6#heroes-and-http) section (`api/heroes`) and _id_ is
|
||||
the number of the hero that you want to retrieve. For example, `api/heroes/11`.
|
||||
|
||||
Add a `HeroService.getHero()` method to make that request:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="getHero" title="src/app/hero.service.ts"></code-example>
|
||||
|
@ -629,6 +634,16 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
|||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a dashboardcomponent}
|
||||
#### _DashboardComponent_
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
title="src/app/dashboard/dashboard.component.html"
|
||||
path="toh-pt6/src/app/dashboard/dashboard.component.html">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a herosearchcomponent}
|
||||
#### _HeroSearchComponent_
|
||||
|
||||
|
|
Loading…
Reference in New Issue