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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user