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

Commit 3324bd9

Browse files
committed
docs(toh-6): fix broken 'Add Hero' and fill in instructional gaps
1 parent ba02c40 commit 3324bd9

File tree

4 files changed

+68
-45
lines changed

4 files changed

+68
-45
lines changed

public/docs/_examples/toh-6/ts/app/heroes.component.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@ <h2>My Heroes</h2>
55
<span class="hero-element">
66
<span class="badge">{{hero.id}}</span> {{hero.name}}
77
</span>
8+
<!-- #docregion delete-hero -->
89
<button class="delete-button" (click)="delete(hero, $event)">Delete</button>
10+
<!-- #enddocregion delete-hero -->
911
</li>
1012
</ul>
1113

14+
<!-- #docregion add-hero -->
1215
<button (click)="addHero()">Add New Hero</button>
1316
<div *ngIf="addingHero">
1417
<my-hero-detail (close)="close($event)"></my-hero-detail>
1518
</div>
19+
<!-- #enddocregion add-hero -->
20+
1621
<div *ngIf="selectedHero">
1722
<h2>
1823
{{selectedHero.name | uppercase}} is my hero

public/docs/_examples/toh-6/ts/app/heroes.component.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ import { Router } from '@angular/router-deprecated';
44

55
import { Hero } from './hero';
66
import { HeroService } from './hero.service';
7+
// #docregion hero-detail-component
8+
import { HeroDetailComponent } from './hero-detail.component';
79

810
@Component({
911
selector: 'my-heroes',
1012
templateUrl: 'app/heroes.component.html',
11-
styleUrls: ['app/heroes.component.css']
13+
styleUrls: ['app/heroes.component.css'],
14+
directives: [HeroDetailComponent]
1215
})
16+
// #enddocregion hero-detail-component
1317
export class HeroesComponent implements OnInit {
1418
heroes: Hero[];
1519
selectedHero: Hero;
@@ -27,6 +31,7 @@ export class HeroesComponent implements OnInit {
2731
.catch(error => this.error = error); // TODO: Display error message
2832
}
2933

34+
// #docregion add
3035
addHero() {
3136
this.addingHero = true;
3237
this.selectedHero = null;
@@ -36,6 +41,7 @@ export class HeroesComponent implements OnInit {
3641
this.addingHero = false;
3742
if (savedHero) { this.getHeroes(); }
3843
}
44+
// #enddocregion add
3945

4046
// #docregion delete
4147
delete(hero: Hero, event: any) {

public/docs/ts/latest/tutorial/toh-pt6.jade

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,22 @@
11
include ../_util-fns
22

33
:marked
4-
# Http
4+
# Getting and Saving Data with HTTP
55

6-
Our application has become a huge success and our stakeholders have expanded the vision to include integration with a hero api.
6+
Our stakeholders appreciate our progress.
7+
Now they want to get the hero data from a server, let users add, edit, and delete heroes,
8+
and save these changes back to the server.
79

8-
The current solution limits us to a fixed set of heroes, but integration with a web server api will make our application much more flexible. We will also be able to add, edit and delete heroes.
9-
10-
In this chapter we will connect our Angular 2 services to make http calls to our new api.
10+
In this chapter we teach our application to make the corresponding http calls to a remote server's web api.
1111
:marked
1212
[Run the live example](/resources/live-examples/toh-6/ts/plnkr.html).
1313

1414
.l-main-section
1515
:marked
1616
## Where We Left Off
17-
Before we continue with our Tour of Heroes, let’s verify that we have the following structure after adding our hero service
18-
and hero detail component. If not, we’ll need to go back and follow the previous chapters.
17+
In the [previous chapter](toh-pt5.html), we learned to navigate between the dashboard and the fixed heroes list, editing a selected hero along the way.
18+
That's our starting point for this chapter.
1919

20-
.filetree
21-
.file angular2-tour-of-heroes
22-
.children
23-
.file app
24-
.children
25-
.file app.component.ts
26-
.file app.component.css
27-
.file dashboard.component.css
28-
.file dashboard.component.html
29-
.file dashboard.component.ts
30-
.file hero.ts
31-
.file hero-detail.component.css
32-
.file hero-detail.component.html
33-
.file hero-detail.component.ts
34-
.file hero.service.ts
35-
.file heroes.component.css
36-
.file heroes.component.html
37-
.file heroes.component.ts
38-
.file main.ts
39-
.file mock-heroes.ts
40-
.file node_modules ...
41-
.file typings ...
42-
.file index.html
43-
.file package.json
44-
.file styles.css
45-
.file systemjs.config.json
46-
.file tsconfig.json
47-
.file typings.json
48-
:marked
4920
### Keep the app transpiling and running
5021
Open a terminal/console window and enter the following command to
5122
start the TypeScript compiler, start the server, and watch for changes:
@@ -243,9 +214,10 @@ code-example(format="." language="bash").
243214
:marked
244215
## Updating Components
245216

246-
Loading heroes using `Http` required no changes outside of `HeroService`, but we added a few new features as well. In the following section we will update our components to use our new methods to add, edit and delete heroes.
217+
Loading heroes using `Http` required no changes outside of `HeroService`, but we added a few new features as well.
218+
In the following section we will update our components to use our new methods to add, edit and delete heroes.
247219

248-
### Add/Edit
220+
### Add/Edit in the *HeroDetailComponent*
249221
We already have `HeroDetailComponent` for viewing details about a specific hero. Add and Edit are natural extensions of the detail view, so we are able to reuse `DetailHeroComponent` with a few tweaks. The original component was created to render existing data, but to add new data we have to initialize the `hero` property to an empty `Hero` object.
250222

251223
+makeExample('toh-6/ts/app/hero-detail.component.ts', 'ngOnInit', 'app/hero-detail.component.ts (ngOnInit)')(format=".")
@@ -267,23 +239,63 @@ code-example(format="." language="bash").
267239
The `emit` "handshake" between `HeroDetailComponent` and `HeroesComponent` is an example of component to component communication. This is a topic for another day, but we have detailed information in our <a href="/docs/ts/latest/cookbook/component-communication.html#!#child-to-parent">Component Interaction Cookbook</a>
268240

269241
:marked
270-
Here is `HeroDetailComponent` with the added save button.
242+
Here is `HeroDetailComponent` with its new save button.
271243

272244
figure.image-display
273245
img(src='/resources/images/devguide/toh/hero-details-save-button.png' alt="Hero Details With Save Button")
274246

275247
:marked
276-
### Delete
248+
### Add/Delete in the *HeroesComponent*
249+
250+
The user can *add* a new hero by clicking a button and entering a name.
251+
252+
When the user clicks the *Add New Hero* button, we display the `HeroDetailComponent`.
253+
We aren't navigating to the component so it won't receive a hero `id`;
254+
As we noted above, that is the component's cue to create and present an empty hero.
255+
256+
Add the following HTML to the `heroes.component.html`, just below the hero list (the `*ngFor`).
257+
+makeExample('toh-6/ts/app/heroes.component.html', 'add-hero', 'app/heroes.component.ts (add)')(format=".")
258+
:marked
259+
The user can *delete* an existing hero by clicking a delete button next to the hero's name.
277260

278-
We have added the option to delete hereos from `HeroesComponent`. `HeroService` will delete the hero, but we still have to filter out the deleted hero from the list to update the view.
261+
Add the following HTML to the `heroes.component.html` right after the name in the repeated `<li>` tag:
262+
+makeExample('toh-6/ts/app/heroes.component.html', 'delete-hero', 'app/heroes.component.ts (delete)')(format=".")
263+
264+
:marked
265+
Now let's fix-up the `HeroesComponent` to support the *add* and *delete* actions in the template.
266+
Let's start with *add*.
279267

280-
+makeExample('toh-6/ts/app/heroes.component.ts', 'delete', 'app/heroes.component.ts (delete)')(format=".")
268+
We're using the `HeroDetailComponent` to capture the new hero information.
269+
We have to tell Angular about that by importing the `HeroDetailComponent` and referencing it in the component metadata `directives` array.
270+
+makeExample('toh-6/ts/app/heroes.component.ts', 'hero-detail-component', 'app/heroes.component.ts (HeroDetailComponent)')(format=".")
271+
.l-sub-section
272+
:marked
273+
These are the same lines that we removed in the previous [Routing](toh-pt5.html) chapter.
274+
We didn't know at the time that we'd need the *HeroDetailComponent* again. So we tidied up.
275+
276+
Now we *must* put these lines back. If we don't, Angular will ignore the `<my-hero-detail>`
277+
tag and pushing the *Add New Hero* button will have no visible effect.
278+
:marked
279+
Next we implement the click handler for the *Add New Hero* button.
281280

281+
+makeExample('toh-6/ts/app/heroes.component.ts', 'add', 'app/heroes.component.ts (add)')(format=".")
282282
:marked
283-
Here is `HeroesComponent` with the delete button.
283+
The `HeroDetailComponent` does most of the work. All we do is toggle an `*ngIf` flag that
284+
swaps it into the DOM when were add a hero and remove it from the DOM when the user is done.
284285

286+
The *delete* logic is a bit trickier.
287+
+makeExample('toh-6/ts/app/heroes.component.ts', 'delete', 'app/heroes.component.ts (delete)')(format=".")
288+
289+
:marked
290+
Of course we delegate the persistence of hero deletion to the `HeroService`.
291+
But the component is still responsible for updating the display.
292+
So the *delete* method removes the deleted hero from the list.
293+
294+
:marked
295+
### Let's see it
296+
Here are the fruits of labor in action:
285297
figure.image-display
286-
img(src='/resources/images/devguide/toh/heroes-list-delete-button.png' alt="Heroes List With Delete Button")
298+
img(src='/resources/images/devguide/toh/toh-http.anim.gif' alt="Heroes List Editting w/ HTTP")
287299

288300
:marked
289301
### Review the App Structure
Loading

0 commit comments

Comments
 (0)