Merge remote-tracking branch 'origin/master'
# Conflicts: # public/docs/ts/latest/tutorial/toh-pt5.jade
This commit is contained in:
commit
6a5f4a0fc2
|
@ -13,6 +13,7 @@ import 'hero_service.dart';
|
||||||
|
|
||||||
@Component(
|
@Component(
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
|
// #docregion template
|
||||||
template: '''
|
template: '''
|
||||||
<h1>{{title}}</h1>
|
<h1>{{title}}</h1>
|
||||||
<h2>My Heroes</h2>
|
<h2>My Heroes</h2>
|
||||||
|
@ -25,6 +26,7 @@ import 'hero_service.dart';
|
||||||
</ul>
|
</ul>
|
||||||
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
|
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
|
||||||
''',
|
''',
|
||||||
|
// #enddocregion template
|
||||||
styles: const [
|
styles: const [
|
||||||
'''
|
'''
|
||||||
.selected {
|
.selected {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/* #docplaster */
|
/* #docregion */
|
||||||
/* #docregion css */
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
color: #999;
|
color: #999;
|
||||||
|
@ -28,4 +27,3 @@ nav a:hover {
|
||||||
nav a.router-link-active {
|
nav a.router-link-active {
|
||||||
color: #039be5;
|
color: #039be5;
|
||||||
}
|
}
|
||||||
/* #enddocregion css */
|
|
||||||
|
|
|
@ -27,20 +27,19 @@ import 'package:angular2_tour_of_heroes/hero_detail_component.dart';
|
||||||
directives: const [ROUTER_DIRECTIVES],
|
directives: const [ROUTER_DIRECTIVES],
|
||||||
providers: const [HeroService, ROUTER_PROVIDERS])
|
providers: const [HeroService, ROUTER_PROVIDERS])
|
||||||
@RouteConfig(const [
|
@RouteConfig(const [
|
||||||
// #docregion dashboard-route
|
// #docregion dashboard-route
|
||||||
const Route(
|
const Route(
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
component: DashboardComponent,
|
component: DashboardComponent,
|
||||||
useAsDefault: true),
|
useAsDefault: true),
|
||||||
// #enddocregion dashboard-route
|
// #enddocregion dashboard-route
|
||||||
// #docregion hero-detail-route
|
// #docregion hero-detail-route
|
||||||
const Route(
|
const Route(
|
||||||
path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent),
|
path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent),
|
||||||
// #enddocregion hero-detail-route
|
// #enddocregion hero-detail-route
|
||||||
const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
|
const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
|
||||||
])
|
])
|
||||||
class AppComponent {
|
class AppComponent {
|
||||||
String title = 'Tour of Heroes';
|
String title = 'Tour of Heroes';
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -15,12 +15,11 @@ import 'heroes_component.dart';
|
||||||
<my-heroes></my-heroes>''',
|
<my-heroes></my-heroes>''',
|
||||||
directives: const [HeroesComponent],
|
directives: const [HeroesComponent],
|
||||||
providers: const [
|
providers: const [
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
ROUTER_PROVIDERS,
|
ROUTER_PROVIDERS,
|
||||||
// #docregion
|
// #docregion
|
||||||
HeroService
|
HeroService
|
||||||
])
|
])
|
||||||
class AppComponent {
|
class AppComponent {
|
||||||
String title = 'Tour of Heroes';
|
String title = 'Tour of Heroes';
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -10,12 +10,12 @@ import 'heroes_component.dart';
|
||||||
|
|
||||||
@Component(
|
@Component(
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
// #docregion template
|
// #docregion template
|
||||||
template: '''
|
template: '''
|
||||||
<h1>{{title}}</h1>
|
<h1>{{title}}</h1>
|
||||||
<a [routerLink]="['Heroes']">Heroes</a>
|
<a [routerLink]="['Heroes']">Heroes</a>
|
||||||
<router-outlet></router-outlet>''',
|
<router-outlet></router-outlet>''',
|
||||||
// #enddocregion template
|
// #enddocregion template
|
||||||
// #docregion directives-and-providers
|
// #docregion directives-and-providers
|
||||||
directives: const [ROUTER_DIRECTIVES],
|
directives: const [ROUTER_DIRECTIVES],
|
||||||
providers: const [ROUTER_PROVIDERS, HeroService]
|
providers: const [ROUTER_PROVIDERS, HeroService]
|
||||||
|
@ -29,4 +29,3 @@ import 'heroes_component.dart';
|
||||||
class AppComponent {
|
class AppComponent {
|
||||||
String title = 'Tour of Heroes';
|
String title = 'Tour of Heroes';
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
/* #docplaster */
|
|
||||||
/* #docregion */
|
/* #docregion */
|
||||||
[class*='col-'] {
|
[class*='col-'] {
|
||||||
float: left;
|
float: left;
|
||||||
|
@ -60,4 +59,3 @@ h4 {
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* #enddocregion */
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:angular2/core.dart';
|
import 'package:angular2/core.dart';
|
||||||
// #docregion import-router
|
// #docregion import-router
|
||||||
import 'package:angular2/router.dart';
|
import 'package:angular2/router.dart';
|
||||||
|
@ -16,22 +18,25 @@ import 'hero_service.dart';
|
||||||
// #docregion css
|
// #docregion css
|
||||||
styleUrls: const ['dashboard_component.css']
|
styleUrls: const ['dashboard_component.css']
|
||||||
// #enddocregion css
|
// #enddocregion css
|
||||||
)
|
)
|
||||||
// #docregion component
|
// #docregion component
|
||||||
class DashboardComponent implements OnInit {
|
class DashboardComponent implements OnInit {
|
||||||
List<Hero> heroes;
|
List<Hero> heroes;
|
||||||
// #docregion ctor
|
|
||||||
|
// #docregion ctor
|
||||||
final Router _router;
|
final Router _router;
|
||||||
final HeroService _heroService;
|
final HeroService _heroService;
|
||||||
|
|
||||||
DashboardComponent(this._heroService, this._router);
|
DashboardComponent(this._heroService, this._router);
|
||||||
// #enddocregion ctor
|
|
||||||
|
|
||||||
ngOnInit() async =>
|
// #enddocregion ctor
|
||||||
|
|
||||||
|
Future<Null> ngOnInit() async {
|
||||||
heroes = (await _heroService.getHeroes()).getRange(1, 5).toList();
|
heroes = (await _heroService.getHeroes()).getRange(1, 5).toList();
|
||||||
|
}
|
||||||
|
|
||||||
// #docregion goto-detail
|
// #docregion goto-detail
|
||||||
gotoDetail(Hero hero) {
|
void gotoDetail(Hero hero) {
|
||||||
var link = [
|
var link = [
|
||||||
'HeroDetail',
|
'HeroDetail',
|
||||||
{'id': hero.id.toString()}
|
{'id': hero.id.toString()}
|
||||||
|
@ -40,4 +45,3 @@ class DashboardComponent implements OnInit {
|
||||||
}
|
}
|
||||||
// #enddocregion goto-detail
|
// #enddocregion goto-detail
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<!-- #docregion -->
|
<!-- #docregion -->
|
||||||
<h3>Top Heroes</h3>
|
<h3>Top Heroes</h3>
|
||||||
<div class="grid grid-pad">
|
<div class="grid grid-pad">
|
||||||
<!-- #docregion click -->
|
<!-- #docregion click -->
|
||||||
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1-4" >
|
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1-4" >
|
||||||
<!-- #enddocregion click -->
|
<!-- #enddocregion click -->
|
||||||
<div class="module hero">
|
<div class="module hero">
|
||||||
<h4>{{hero.name}}</h4>
|
<h4>{{hero.name}}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion imports
|
// #docregion imports
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:angular2/core.dart';
|
import 'package:angular2/core.dart';
|
||||||
|
|
||||||
import 'hero.dart';
|
import 'hero.dart';
|
||||||
|
@ -9,17 +11,16 @@ import 'hero_service.dart';
|
||||||
// #docregion component
|
// #docregion component
|
||||||
@Component(
|
@Component(
|
||||||
selector: 'my-dashboard',
|
selector: 'my-dashboard',
|
||||||
templateUrl: 'dashboard_component.html'
|
templateUrl: 'dashboard_component.html')
|
||||||
)
|
|
||||||
class DashboardComponent implements OnInit {
|
class DashboardComponent implements OnInit {
|
||||||
List<Hero> heroes;
|
List<Hero> heroes;
|
||||||
final HeroService _heroService;
|
final HeroService _heroService;
|
||||||
|
|
||||||
DashboardComponent(this._heroService);
|
DashboardComponent(this._heroService);
|
||||||
|
|
||||||
ngOnInit() async =>
|
Future<Null> ngOnInit() async {
|
||||||
heroes = (await _heroService.getHeroes()).getRange(1, 5).toList();
|
heroes = (await _heroService.getHeroes()).getRange(1, 5).toList();
|
||||||
|
}
|
||||||
|
|
||||||
gotoDetail(){ /* not implemented yet */}
|
gotoDetail() {/* not implemented yet */}
|
||||||
}
|
}
|
||||||
// #enddocregion component
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
// #docregion v2
|
// #docregion v2
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:html';
|
import 'dart:html';
|
||||||
|
|
||||||
// #docregion import-oninit
|
// #docregion import-oninit
|
||||||
|
@ -20,37 +21,35 @@ import 'hero_service.dart';
|
||||||
selector: 'my-hero-detail',
|
selector: 'my-hero-detail',
|
||||||
// #docregion template-url
|
// #docregion template-url
|
||||||
templateUrl: 'hero_detail_component.html',
|
templateUrl: 'hero_detail_component.html',
|
||||||
// #enddocregion template-url
|
// #enddocregion template-url, v2
|
||||||
// #enddocregion v2
|
|
||||||
styleUrls: const ['hero_detail_component.css']
|
styleUrls: const ['hero_detail_component.css']
|
||||||
// #docregion v2
|
// #docregion v2
|
||||||
)
|
)
|
||||||
// #enddocregion extract-template
|
// #enddocregion extract-template
|
||||||
// #docregion implement
|
// #docregion implement
|
||||||
class HeroDetailComponent implements OnInit {
|
class HeroDetailComponent implements OnInit {
|
||||||
// #enddocregion implement
|
// #enddocregion implement
|
||||||
Hero hero;
|
Hero hero;
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
final HeroService _heroService;
|
final HeroService _heroService;
|
||||||
final RouteParams _routeParams;
|
final RouteParams _routeParams;
|
||||||
|
|
||||||
HeroDetailComponent(this._heroService, this._routeParams);
|
HeroDetailComponent(this._heroService, this._routeParams);
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
// #docregion ng-oninit
|
// #docregion ng-oninit
|
||||||
ngOnInit() async {
|
Future<Null> ngOnInit() async {
|
||||||
// #docregion get-id
|
// #docregion get-id
|
||||||
var id = int.parse(_routeParams.get('id'));
|
var idString = _routeParams.get('id');
|
||||||
|
var id = int.parse(idString, onError: (_) => null);
|
||||||
// #enddocregion get-id
|
// #enddocregion get-id
|
||||||
hero = await (_heroService.getHero(id));
|
if (id != null) hero = await (_heroService.getHero(id));
|
||||||
}
|
}
|
||||||
// #enddocregion ng-oninit
|
// #enddocregion ng-oninit
|
||||||
|
|
||||||
// #docregion go-back
|
// #docregion go-back
|
||||||
goBack() {
|
void goBack() {
|
||||||
window.history.back();
|
window.history.back();
|
||||||
}
|
}
|
||||||
// #enddocregion go-back
|
// #enddocregion go-back
|
||||||
}
|
}
|
||||||
// #enddocregion v2
|
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// #docplaster
|
|
||||||
|
|
||||||
// #docregion
|
// #docregion
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
@ -10,18 +8,16 @@ import 'mock_heroes.dart';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class HeroService {
|
class HeroService {
|
||||||
Future<List<Hero>> getHeroes() async => HEROES;
|
Future<List<Hero>> getHeroes() async => mockHeroes;
|
||||||
|
|
||||||
// See the "Take it slow" appendix
|
// See the "Take it slow" appendix
|
||||||
Future<List<Hero>> getHeroesSlowly() {
|
Future<List<Hero>> getHeroesSlowly() {
|
||||||
return new Future<List<Hero>>.delayed(
|
return new Future<List<Hero>>.delayed(
|
||||||
const Duration(seconds: 2), () => HEROES // 2 seconds
|
const Duration(seconds: 2), () => mockHeroes);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#docregion get-hero
|
// #docregion get-hero
|
||||||
Future<Hero> getHero(int id) async =>
|
Future<Hero> getHero(int id) async =>
|
||||||
HEROES.where((hero) => hero.id == id).first;
|
(await getHeroes()).firstWhere((hero) => hero.id == id);
|
||||||
//#enddocregion get-hero
|
// #enddocregion get-hero
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -9,22 +9,19 @@ import 'hero.dart';
|
||||||
import 'hero_detail_component.dart';
|
import 'hero_detail_component.dart';
|
||||||
import 'hero_service.dart';
|
import 'hero_service.dart';
|
||||||
|
|
||||||
// #docregion metadata
|
// #docregion metadata, heroes-component-renaming
|
||||||
// #docregion heroes-component-renaming
|
|
||||||
@Component(
|
@Component(
|
||||||
selector: 'my-heroes',
|
selector: 'my-heroes',
|
||||||
// #enddocregion heroes-component-renaming
|
// #enddocregion heroes-component-renaming
|
||||||
templateUrl: 'heroes_component.html',
|
templateUrl: 'heroes_component.html',
|
||||||
styleUrls: const ['heroes_component.css'],
|
styleUrls: const ['heroes_component.css'],
|
||||||
directives: const [HeroDetailComponent]
|
directives: const [HeroDetailComponent]
|
||||||
// #docregion heroes-component-renaming
|
// #docregion heroes-component-renaming
|
||||||
)
|
)
|
||||||
// #enddocregion heroes-component-renaming
|
// #enddocregion heroes-component-renaming, metadata
|
||||||
// #enddocregion metadata
|
// #docregion class, heroes-component-renaming
|
||||||
// #docregion class
|
|
||||||
// #docregion heroes-component-renaming
|
|
||||||
class HeroesComponent implements OnInit {
|
class HeroesComponent implements OnInit {
|
||||||
// #enddocregion heroes-component-renaming
|
// #enddocregion heroes-component-renaming
|
||||||
final Router _router;
|
final Router _router;
|
||||||
final HeroService _heroService;
|
final HeroService _heroService;
|
||||||
List<Hero> heroes;
|
List<Hero> heroes;
|
||||||
|
@ -32,7 +29,7 @@ class HeroesComponent implements OnInit {
|
||||||
|
|
||||||
HeroesComponent(this._heroService, this._router);
|
HeroesComponent(this._heroService, this._router);
|
||||||
|
|
||||||
Future getHeroes() async {
|
Future<Null> getHeroes() async {
|
||||||
heroes = await _heroService.getHeroes();
|
heroes = await _heroService.getHeroes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,10 +39,7 @@ class HeroesComponent implements OnInit {
|
||||||
|
|
||||||
void onSelect(Hero hero) { selectedHero = hero; }
|
void onSelect(Hero hero) { selectedHero = hero; }
|
||||||
|
|
||||||
Future gotoDetail() =>
|
Future<Null> gotoDetail() =>
|
||||||
_router.navigate(['HeroDetail', {'id': selectedHero.id.toString()}]);
|
_router.navigate(['HeroDetail', {'id': selectedHero.id.toString()}]);
|
||||||
// #docregion heroes-component-renaming
|
// #docregion heroes-component-renaming
|
||||||
}
|
}
|
||||||
// #enddocregion heroes-component-renaming
|
|
||||||
// #enddocregion class
|
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -17,5 +17,3 @@
|
||||||
</h2>
|
</h2>
|
||||||
<button (click)="gotoDetail()">View Details</button>
|
<button (click)="gotoDetail()">View Details</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion mini-detail -->
|
|
||||||
<!-- #enddocregion -->
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'hero.dart';
|
import 'hero.dart';
|
||||||
|
|
||||||
final List<Hero> HEROES = [
|
final List<Hero> mockHeroes = [
|
||||||
new Hero(11, 'Mr. Nice'),
|
new Hero(11, 'Mr. Nice'),
|
||||||
new Hero(12, 'Narco'),
|
new Hero(12, 'Narco'),
|
||||||
new Hero(13, 'Bombasto'),
|
new Hero(13, 'Bombasto'),
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<!-- #docregion head -->
|
<!-- #docregion head, base-href -->
|
||||||
<!-- #docregion base-href -->
|
|
||||||
<head>
|
<head>
|
||||||
<base href="/"> <!-- For testing using pub serve directly -->
|
<!-- For testing using pub serve directly use: -->
|
||||||
<!-- base href="/dart/web/" --> <!-- For testing in WebStorm -->
|
<base href="/">
|
||||||
|
<!-- For testing in WebStorm use: -->
|
||||||
|
<!-- base href="/dart/web/" -->
|
||||||
<!-- #enddocregion base-href -->
|
<!-- #enddocregion base-href -->
|
||||||
<title>Angular 2 Tour of Heroes</title>
|
<title>Angular 2 Tour of Heroes</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
|
@ -2,6 +2,6 @@ import 'package:angular2/platform/browser.dart';
|
||||||
|
|
||||||
import 'package:angular2_tour_of_heroes/app_component.dart';
|
import 'package:angular2_tour_of_heroes/app_component.dart';
|
||||||
|
|
||||||
main() {
|
void main() {
|
||||||
bootstrap(AppComponent);
|
bootstrap(AppComponent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* #docregion toh-excerpt */
|
||||||
|
/* Master Styles */
|
||||||
|
h1 {
|
||||||
|
color: #369;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 250%;
|
||||||
|
}
|
||||||
|
h2, h3 {
|
||||||
|
color: #444;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-weight: lighter;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 2em;
|
||||||
|
}
|
||||||
|
body, input[text], button {
|
||||||
|
color: #888;
|
||||||
|
font-family: Cambria, Georgia;
|
||||||
|
}
|
||||||
|
/* . . . */
|
||||||
|
/* everywhere else */
|
||||||
|
* {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
|
@ -3,10 +3,10 @@ include ../_util-fns
|
||||||
:marked
|
:marked
|
||||||
# Routing Around the App
|
# Routing Around the App
|
||||||
We received new requirements for our Tour of Heroes application:
|
We received new requirements for our Tour of Heroes application:
|
||||||
* add a *Dashboard* view.
|
* Add a *Dashboard* view.
|
||||||
* navigate between the *Heroes* and *Dashboard* views.
|
* Navigate between the *Heroes* and *Dashboard* views.
|
||||||
* clicking on a hero in either view navigates to a detail view of the selected hero.
|
* Clicking on a hero in either view navigates to a detail view of the selected hero.
|
||||||
* clicking a *deep link* in an email opens the detail view for a particular hero.
|
* Clicking a *deep link* in an email opens the detail view for a particular hero.
|
||||||
|
|
||||||
When we’re done, users will be able to navigate the app like this:
|
When we’re done, users will be able to navigate the app like this:
|
||||||
figure.image-display
|
figure.image-display
|
||||||
|
@ -16,7 +16,7 @@ figure.image-display
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
|
The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
|
||||||
than we will in this tour.
|
than we will in this tutorial.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
|
p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
|
||||||
|
|
||||||
|
@ -54,13 +54,13 @@ code-example(language="bash").
|
||||||
The application runs and updates automatically as we continue to build the Tour of Heroes.
|
The application runs and updates automatically as we continue to build the Tour of Heroes.
|
||||||
|
|
||||||
## Action plan
|
## Action plan
|
||||||
Here's our plan
|
Here's our plan:
|
||||||
|
|
||||||
* turn `AppComponent` into an application shell that only handles navigation.
|
* Turn `AppComponent` into an application shell that only handles navigation
|
||||||
* relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`
|
* Relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`
|
||||||
* add routing
|
* Add routing
|
||||||
* create a new `DashboardComponent`
|
* Create a new `DashboardComponent`
|
||||||
* tie the *Dashboard* into the navigation structure.
|
* Tie the *Dashboard* into the navigation structure
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -82,13 +82,13 @@ code-example(language="bash").
|
||||||
Instead of moving anything out of `AppComponent`, we'll just rename it `HeroesComponent`
|
Instead of moving anything out of `AppComponent`, we'll just rename it `HeroesComponent`
|
||||||
and create a new `AppComponent` shell separately.
|
and create a new `AppComponent` shell separately.
|
||||||
|
|
||||||
The steps are:
|
The steps are to rename:
|
||||||
* rename `app_component.dart` file to `heroes_component.dart`.
|
* `app_component.dart` file to `heroes_component.dart`
|
||||||
* rename the `AppComponent` class to `HeroesComponent`.
|
* `AppComponent` class to `HeroesComponent`
|
||||||
* rename the selector `my-app` to `my-heroes`.
|
* Selector `my-app` to `my-heroes`
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
+makeExample('toh-5/dart/lib/heroes_component.dart', 'heroes-component-renaming', 'lib/heroes_component.dart (renaming)')(format=".")
|
+makeExample('toh-5/dart/lib/heroes_component.dart', 'heroes-component-renaming', 'lib/heroes_component.dart (showing renamings only)')(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
## Create *AppComponent*
|
## Create *AppComponent*
|
||||||
|
@ -149,14 +149,14 @@ code-example(language="bash").
|
||||||
|
|
||||||
The Angular router is a combination of multiple services (`ROUTER_PROVIDERS`), multiple directives (`ROUTER_DIRECTIVES`),
|
The Angular router is a combination of multiple services (`ROUTER_PROVIDERS`), multiple directives (`ROUTER_DIRECTIVES`),
|
||||||
and a configuration annotation (`RouteConfig`). We'll get them all by importing `router.dart`:
|
and a configuration annotation (`RouteConfig`). We'll get them all by importing `router.dart`:
|
||||||
+makeExample('toh-5/dart/lib/app_component_2.dart', 'import-router', 'app_component.dart (router imports)')(format=".")
|
+makeExample('toh-5/dart/lib/app_component_2.dart', 'import-router', 'lib/app_component.dart (router imports)')(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
The *Component Router* is a service. Like any service, we have to make it
|
The *Component Router* is a service. Like any service, we have to make it
|
||||||
available to the application by adding it to the `providers` list.
|
available to the application by adding it to the `providers` list.
|
||||||
|
|
||||||
Let's update the `directives` and `providers` metadata lists to *include* the router assets.
|
Let's update the `directives` and `providers` metadata lists to *include* the router assets.
|
||||||
+makeExample('toh-5/dart/lib/app_component_2.dart', 'directives-and-providers', 'app_component.dart (directives and providers)')(format=".")
|
+makeExample('toh-5/dart/lib/app_component_2.dart', 'directives-and-providers', 'lib/app_component.dart (directives and providers)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Notice that we also removed the `HeroesComponent` from the `directives` list.
|
Notice that we also removed the `HeroesComponent` from the `directives` list.
|
||||||
`AppComponent` no longer shows heroes; that will be the router's job.
|
`AppComponent` no longer shows heroes; that will be the router's job.
|
||||||
|
@ -171,7 +171,7 @@ code-example(language="bash").
|
||||||
pastes a URL into the browser address bar.
|
pastes a URL into the browser address bar.
|
||||||
|
|
||||||
Let's define our first route, a route to the `HeroesComponent`.
|
Let's define our first route, a route to the `HeroesComponent`.
|
||||||
+makeExample('toh-5/dart/lib/app_component_2.dart', 'route-config', 'app_component.dart (RouteConfig for heroes)')(format=".")
|
+makeExample('toh-5/dart/lib/app_component_2.dart', 'route-config', 'lib/app_component.dart (RouteConfig for heroes)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
`@RouteConfig` takes a list of *route definitions*.
|
`@RouteConfig` takes a list of *route definitions*.
|
||||||
We have only one route definition at the moment but rest assured, we'll add more.
|
We have only one route definition at the moment but rest assured, we'll add more.
|
||||||
|
@ -202,7 +202,7 @@ code-example(language="bash").
|
||||||
We add an anchor tag to the template which, when clicked, triggers navigation to the `HeroesComponent`.
|
We add an anchor tag to the template which, when clicked, triggers navigation to the `HeroesComponent`.
|
||||||
|
|
||||||
The revised template looks like this:
|
The revised template looks like this:
|
||||||
+makeExample('toh-5/dart/lib/app_component_2.dart', 'template', 'app_component.dart (template for Heroes)')(format=".")
|
+makeExample('toh-5/dart/lib/app_component_2.dart', 'template', 'lib/app_component.dart (template v1)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Notice the `[routerLink]` binding in the anchor tag.
|
Notice the `[routerLink]` binding in the anchor tag.
|
||||||
We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to a list
|
We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to a list
|
||||||
|
@ -249,7 +249,7 @@ code-example(language="bash").
|
||||||
Import the `DashboardComponent` so we can reference it in the dashboard route definition.
|
Import the `DashboardComponent` so we can reference it in the dashboard route definition.
|
||||||
|
|
||||||
Add the following `'Dashboard'` route definition to the `@RouteConfig` list of definitions.
|
Add the following `'Dashboard'` route definition to the `@RouteConfig` list of definitions.
|
||||||
+makeExample('toh-5/dart/lib/app_component.dart','dashboard-route', 'app_component.dart (Dashboard Route)')(format=".")
|
+makeExample('toh-5/dart/lib/app_component.dart','dashboard-route', 'lib/app_component.dart (Dashboard route)')(format=".")
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
**useAsDefault**
|
**useAsDefault**
|
||||||
|
@ -264,7 +264,7 @@ code-example(language="bash").
|
||||||
:marked
|
:marked
|
||||||
Finally, add a dashboard navigation link to the template, just above the *Heroes* link.
|
Finally, add a dashboard navigation link to the template, just above the *Heroes* link.
|
||||||
|
|
||||||
+makeExample('toh-5/dart/lib/app_component.dart','template', 'app_component.dart (template)')(format=".")
|
+makeExample('toh-5/dart/lib/app_component.dart','template', 'lib/app_component.dart (template)')(format=".")
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
We nestled the two links within `<nav>` tags.
|
We nestled the two links within `<nav>` tags.
|
||||||
|
@ -282,10 +282,12 @@ code-example(language="bash").
|
||||||
+makeExample('toh-5/dart/lib/dashboard_component.dart', 'template-url', 'lib/dashboard_component.dart (templateUrl)')(format=".")
|
+makeExample('toh-5/dart/lib/dashboard_component.dart', 'template-url', 'lib/dashboard_component.dart (templateUrl)')(format=".")
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
We specify the path _all the way back to the application root_. Angular doesn't support module-relative paths.
|
We specify the path _all the way back to the application root_ —
|
||||||
|
because Angular doesn't support relative paths _by default_.
|
||||||
|
We _can_ switch to [component-relative paths](../cookbook/component-relative-paths.html) if we prefer.
|
||||||
:marked
|
:marked
|
||||||
Create that file with these contents:
|
Create that file with these contents:
|
||||||
+makeExample('toh-5/dart/lib/dashboard_component.html', null, 'dashboard_component.html')(format=".")
|
+makeExample('toh-5/dart/lib/dashboard_component.html', null, 'lib/dashboard_component.html')(format=".")
|
||||||
:marked
|
:marked
|
||||||
We use `*ngFor` once again to iterate over a list of heroes and display their names.
|
We use `*ngFor` once again to iterate over a list of heroes and display their names.
|
||||||
We added extra `<div>` elements to help with styling later in this chapter.
|
We added extra `<div>` elements to help with styling later in this chapter.
|
||||||
|
@ -302,14 +304,13 @@ code-example(language="bash").
|
||||||
and added it to the `providers` list of the top level `AppComponent`.
|
and added it to the `providers` list of the top level `AppComponent`.
|
||||||
|
|
||||||
That move created a singleton `HeroService` instance, available to *all* components of the application.
|
That move created a singleton `HeroService` instance, available to *all* components of the application.
|
||||||
We'll inject and use it here in the `DashboardComponent` .
|
Angular will inject `HeroService` and we'll use it here in the `DashboardComponent`.
|
||||||
|
|
||||||
### Get heroes
|
### Get heroes
|
||||||
Open the `dashboard_component.dart` and add the requisite `import` statements.
|
Open the `dashboard_component.dart` and add the requisite `import` statements.
|
||||||
+makeExample('toh-5/dart/lib/dashboard_component_2.dart','imports', 'lib/dashboard_component.dart (imports)')(format=".")
|
+makeExample('toh-5/dart/lib/dashboard_component_2.dart','imports', 'lib/dashboard_component.dart (imports)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
We need `OnInit` interface because we'll initialize the heroes in the `ngOnInit` method as we've done before.
|
We need `OnInit` interface because we'll initialize the heroes in the `ngOnInit` method as we've done before.
|
||||||
We need the `Hero` and `HeroService` symbols in order to reference those types.
|
|
||||||
|
|
||||||
Now implement the `DashboardComponent` class like this:
|
Now implement the `DashboardComponent` class like this:
|
||||||
+makeExample('toh-5/dart/lib/dashboard_component_2.dart','component', 'lib/dashboard_component.dart (class)')
|
+makeExample('toh-5/dart/lib/dashboard_component_2.dart','component', 'lib/dashboard_component.dart (class)')
|
||||||
|
@ -361,7 +362,7 @@ code-example(format='').
|
||||||
### Configure a Route with a Parameter
|
### Configure a Route with a Parameter
|
||||||
|
|
||||||
Here's the *route definition* we'll use.
|
Here's the *route definition* we'll use.
|
||||||
+makeExample('toh-5/dart/lib/app_component.dart','hero-detail-route', 'lib/app_component.dart (Route to HeroDetailComponent)')(format=".")
|
+makeExample('toh-5/dart/lib/app_component.dart','hero-detail-route', 'lib/app_component.dart (route to HeroDetailComponent)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
The colon (:) in the path indicates that `:id` is a placeholder to be filled with a specific hero `id`
|
The colon (:) in the path indicates that `:id` is a placeholder to be filled with a specific hero `id`
|
||||||
when navigating to the `HeroDetailComponent`.
|
when navigating to the `HeroDetailComponent`.
|
||||||
|
@ -386,7 +387,7 @@ code-example(format='').
|
||||||
:marked
|
:marked
|
||||||
## Revise the *HeroDetailComponent*
|
## Revise the *HeroDetailComponent*
|
||||||
|
|
||||||
Before we rewrite the `HeroDetailComponent`, let's remember what it looks like now:
|
Before we rewrite the `HeroDetailComponent`, let's review what it looks like now:
|
||||||
|
|
||||||
+makeExample('toh-4/dart/lib/hero_detail_component.dart', null, 'lib/hero_detail_component.dart (current)')
|
+makeExample('toh-4/dart/lib/hero_detail_component.dart', null, 'lib/hero_detail_component.dart (current)')
|
||||||
:marked
|
:marked
|
||||||
|
@ -394,12 +395,12 @@ code-example(format='').
|
||||||
|
|
||||||
We will no longer receive the hero in a parent component property binding.
|
We will no longer receive the hero in a parent component property binding.
|
||||||
The new `HeroDetailComponent` should take the `id` parameter from the router's `RouteParams` service
|
The new `HeroDetailComponent` should take the `id` parameter from the router's `RouteParams` service
|
||||||
and use the `HeroService` to fetch the hero with that `id` from storage.
|
and use the `HeroService` to fetch the hero with that `id`.
|
||||||
|
|
||||||
We need an import statement to reference the `RouteParams`.
|
We need an import statement to reference the `RouteParams`.
|
||||||
+makeExample('toh-5/dart/lib/hero_detail_component.dart', 'import-route-params')(format=".")
|
+makeExample('toh-5/dart/lib/hero_detail_component.dart', 'import-route-params')(format=".")
|
||||||
:marked
|
:marked
|
||||||
We import the `HeroService`so we can fetch a hero`.
|
We import the `HeroService`so we can fetch a hero.
|
||||||
+makeExample('toh-5/dart/lib/hero_detail_component.dart', 'import-hero-service')(format=".")
|
+makeExample('toh-5/dart/lib/hero_detail_component.dart', 'import-hero-service')(format=".")
|
||||||
:marked
|
:marked
|
||||||
We import the `OnInit` interface because we'll call the `HeroService` inside the `ngOnInit` component lifecycle hook.
|
We import the `OnInit` interface because we'll call the `HeroService` inside the `ngOnInit` component lifecycle hook.
|
||||||
|
@ -455,13 +456,11 @@ code-example(format='').
|
||||||
:marked
|
:marked
|
||||||
Here's the (nearly) finished `HeroDetailComponent`:
|
Here's the (nearly) finished `HeroDetailComponent`:
|
||||||
+makeExample('toh-5/dart/lib/hero_detail_component.dart', 'v2', 'lib/hero_detail_component.dart (latest)')(format=".")
|
+makeExample('toh-5/dart/lib/hero_detail_component.dart', 'v2', 'lib/hero_detail_component.dart (latest)')(format=".")
|
||||||
:marked
|
|
||||||
|
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Select a *Dashboard* Hero
|
## Select a *Dashboard* Hero
|
||||||
When a user selects a hero in the dashboard, the app should navigate to the `HeroDetailComponent` to view and edit the selected hero..
|
When a user selects a hero in the dashboard, the app should navigate to the `HeroDetailComponent` to view and edit the selected hero.
|
||||||
|
|
||||||
In the dashboard template we bound each hero's click event to the `gotoDetail` method, passing along the selected `hero` entity.
|
In the dashboard template we bound each hero's click event to the `gotoDetail` method, passing along the selected `hero` entity.
|
||||||
+makeExample('toh-5/dart/lib/dashboard_component.html','click', 'lib/dashboard_component.html (click binding)')(format=".")
|
+makeExample('toh-5/dart/lib/dashboard_component.html','click', 'lib/dashboard_component.html (click binding)')(format=".")
|
||||||
|
@ -484,7 +483,7 @@ code-example(format='').
|
||||||
+makeExample('toh-5/dart/lib/app_component.dart','hero-detail-route', 'lib/app_component.dart (hero detail route)')(format=".")
|
+makeExample('toh-5/dart/lib/app_component.dart','hero-detail-route', 'lib/app_component.dart (hero detail route)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
The `DashboardComponent` doesn't have the router yet. We obtain it in the usual way:
|
The `DashboardComponent` doesn't have the router yet. We obtain it in the usual way:
|
||||||
`import` the `router` reference and inject it in the constructor (along with the `HeroService`):
|
import the `router` reference and inject it in the constructor (along with the `HeroService`):
|
||||||
|
|
||||||
+makeExample('toh-5/dart/lib/dashboard_component.dart','import-router', 'lib/dashboard_component.dart (excerpts)')(format=".")
|
+makeExample('toh-5/dart/lib/dashboard_component.dart','import-router', 'lib/dashboard_component.dart (excerpts)')(format=".")
|
||||||
+makeExample('toh-5/dart/lib/dashboard_component.dart','ctor')(format=".")
|
+makeExample('toh-5/dart/lib/dashboard_component.dart','ctor')(format=".")
|
||||||
|
@ -499,9 +498,7 @@ code-example(format='').
|
||||||
That component's current template exhibits a "master/detail" style with the list of heroes
|
That component's current template exhibits a "master/detail" style with the list of heroes
|
||||||
at the top and details of the selected hero below.
|
at the top and details of the selected hero below.
|
||||||
|
|
||||||
**[TODO: Add example, once it exists.]**
|
+makeExample('toh-4/dart/lib/app_component.dart','template', 'lib/heroes_component.dart (current template)')(format=".")
|
||||||
|
|
||||||
// makeExample('toh-4/dart/lib/app_component.dart','template', 'lib/heroes_component.dart (current template)')(format=".")
|
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Delete the last line of the template with the `<my-hero-detail>` tags.
|
Delete the last line of the template with the `<my-hero-detail>` tags.
|
||||||
|
@ -525,7 +522,7 @@ figure.image-display
|
||||||
### Format with the *UpperCasePipe*
|
### Format with the *UpperCasePipe*
|
||||||
|
|
||||||
Notice that the hero's name is displayed in CAPITAL LETTERS. That's the effect of the `UpperCasePipe`
|
Notice that the hero's name is displayed in CAPITAL LETTERS. That's the effect of the `UpperCasePipe`
|
||||||
that we slipped into the interpolation binding. Look for it right after the pipe operator, ( | ).
|
that we slipped into the interpolation binding. Look for it right after the pipe operator ( | ).
|
||||||
+makeExample('toh-5/dart/lib/heroes_component.html','pipe')(format=".")
|
+makeExample('toh-5/dart/lib/heroes_component.html','pipe')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Pipes are a good way to format strings, currency amounts, dates and other display data.
|
Pipes are a good way to format strings, currency amounts, dates and other display data.
|
||||||
|
@ -546,14 +543,19 @@ figure.image-display
|
||||||
1. *Cut-and-paste* the styles contents into a new `heroes_component.css` file.
|
1. *Cut-and-paste* the styles contents into a new `heroes_component.css` file.
|
||||||
1. *Set* the component metadata's `templateUrl` and `styleUrls` properties to refer to both files.
|
1. *Set* the component metadata's `templateUrl` and `styleUrls` properties to refer to both files.
|
||||||
|
|
||||||
The revised component data looks like this:
|
Because the template for `HeroesComponent` no longer uses `HeroDetailComponent`
|
||||||
|
directly — instead using the router to _navigate_ to it — we can
|
||||||
|
remove `HeroDetailComponent` from the directives list. That
|
||||||
|
list is now empty, so we can remove the `directives` argument. The revised
|
||||||
|
`@Component` looks like this:
|
||||||
|
|
||||||
+makeExample('toh-5/dart/lib/heroes_component.dart', 'metadata', 'lib/heroes_component.dart (revised metadata)')(format=".")
|
+makeExample('toh-5/dart/lib/heroes_component.dart', 'metadata', 'lib/heroes_component.dart (revised metadata)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Now we can see what's going on as we update the component class along the same lines as the dashboard:
|
Now we can see what's going on as we update the component class along the same lines as the dashboard:
|
||||||
1. Import the `router`
|
1. Import the `router`
|
||||||
1. Inject the `router` in the constructor (along with the `HeroService`)
|
1. Inject the `router` in the constructor (along with the `HeroService`)
|
||||||
1. Implement the `gotoDetail` method by calling the `router.navigate` method
|
1. Implement the `gotoDetail` method by calling the `router.navigate` method
|
||||||
with a two-part 'HeroDetail' *link parameters list*.
|
with a two-part `HeroDetail` *link parameters list*.
|
||||||
|
|
||||||
Here's the revised component class:
|
Here's the revised component class:
|
||||||
+makeExample('toh-5/dart/lib/heroes_component.dart', 'class', 'lib/heroes_component.dart (class)')
|
+makeExample('toh-5/dart/lib/heroes_component.dart', 'class', 'lib/heroes_component.dart (class)')
|
||||||
|
@ -608,7 +610,7 @@ lib/dashboard_component.css`)
|
||||||
We cooperated by surrounding those links in `<nav>` tags.
|
We cooperated by surrounding those links in `<nav>` tags.
|
||||||
|
|
||||||
Add a `app_component.css` file to the `app` folder with the following content.
|
Add a `app_component.css` file to the `app` folder with the following content.
|
||||||
+makeExample('toh-5/dart/lib/app_component.css', 'css', 'lib/app_component.css (Navigation Styles)')
|
+makeExample('toh-5/dart/lib/app_component.css', '', 'lib/app_component.css (navigation styles)')
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
**The *router-link-active* class**
|
**The *router-link-active* class**
|
||||||
|
@ -627,11 +629,20 @@ lib/dashboard_component.css`)
|
||||||
We can also create styles at the *application level* outside of any component.
|
We can also create styles at the *application level* outside of any component.
|
||||||
|
|
||||||
Our designers provided some basic styles to apply to elements across the entire app.
|
Our designers provided some basic styles to apply to elements across the entire app.
|
||||||
Add the following to a new file named `styles.css` in the root folder.
|
These correspond to the full set of master styles that we
|
||||||
+makeExample('toh-5/ts/styles.1.css', '', 'styles.css (App Styles)')(format=".")
|
introduced earlier (see
|
||||||
|
[QuickStart, "Add some style"](../quickstart.html#!#add-some-style)).
|
||||||
|
Here is an excerpt.
|
||||||
|
|
||||||
|
+makeExample('toh-5/ts/styles.1.css', 'toh-excerpt', 'styles.css (app styles excerpt)')(format=".")
|
||||||
|
|
||||||
|
- var styles_css = 'https://raw.githubusercontent.com/angular/angular.io/master/public/docs/_examples/styles.css'
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Reference this stylesheet within the `index.html` in the traditional manner.
|
Add a new file named `styles.css` in the root folder, if there isn't one already.
|
||||||
|
Ensure that it contains the [master styles given here](!{styles_css}).
|
||||||
|
|
||||||
|
If necessary, also edit `index.html` to refer to this stylesheet.
|
||||||
+makeExample('toh-5/ts/index.html','css', 'index.html (link ref)')(format=".")
|
+makeExample('toh-5/ts/index.html','css', 'index.html (link ref)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Look at the app now. Our dashboard, heroes, and navigation links are styling!
|
Look at the app now. Our dashboard, heroes, and navigation links are styling!
|
||||||
|
@ -642,10 +653,11 @@ figure.image-display
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Application structure and code
|
## Application structure and code
|
||||||
|
p.
|
||||||
Review the sample source code [in the live example for this chapter](/resources/live-examples/toh-5/ts/plnkr.html).
|
Review the sample source code in the #[+liveExampleLink2('', 'toh-5')] for this chapter.
|
||||||
Verify that we have the following structure:
|
Verify that we have the following structure:
|
||||||
|
|
||||||
|
:marked
|
||||||
.filetree
|
.filetree
|
||||||
.file angular2-tour-of-heroes
|
.file angular2-tour-of-heroes
|
||||||
.children
|
.children
|
||||||
|
@ -672,7 +684,6 @@ figure.image-display
|
||||||
.file index.html
|
.file index.html
|
||||||
.file styles.css
|
.file styles.css
|
||||||
.file pubspec.yaml
|
.file pubspec.yaml
|
||||||
:marked
|
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -681,15 +692,15 @@ figure.image-display
|
||||||
### The Road Behind
|
### The Road Behind
|
||||||
We travelled a great distance in this chapter
|
We travelled a great distance in this chapter
|
||||||
- We added the Angular *Component Router* to navigate among different components.
|
- We added the Angular *Component Router* to navigate among different components.
|
||||||
- We learned how to create router links to represent navigation menu items
|
- We learned how to create router links to represent navigation menu items.
|
||||||
- We used router parameters to navigate to the details of user selected hero
|
- We used router parameters to navigate to the details of user selected hero.
|
||||||
- We shared the `HeroService` among multiple components
|
- We shared the `HeroService` among multiple components.
|
||||||
- We moved HTML and CSS out of the component file and into their own files.
|
- We moved HTML and CSS out of the component file and into their own files.
|
||||||
- We added the `uppercase` pipe to format data
|
- We added the `uppercase` pipe to format data.
|
||||||
|
|
||||||
### The Road Ahead
|
### The Road Ahead
|
||||||
We have much of the foundation we need to build an application.
|
We have much of the foundation we need to build an application.
|
||||||
We're still missing a key piece: remote data access.
|
We're still missing a key piece: remote data access.
|
||||||
|
|
||||||
In a forthcoming tutorial chapter,
|
In the next chapter,
|
||||||
we’ll replace our mock data with data retrieved from a server using http.
|
we’ll replace our mock data with data retrieved from a server using http.
|
||||||
|
|
|
@ -87,20 +87,22 @@ code-example(language="bash").
|
||||||
我们继续构建《英雄指南》,应用也会保持运行并自动更新。
|
我们继续构建《英雄指南》,应用也会保持运行并自动更新。
|
||||||
|
|
||||||
## Action plan
|
## Action plan
|
||||||
|
|
||||||
## 行动计划
|
## 行动计划
|
||||||
Here's our plan
|
|
||||||
|
|
||||||
下面是我们的计划
|
Here's our plan:
|
||||||
|
|
||||||
* turn `AppComponent` into an application shell that only handles navigation,
|
下面是我们的计划:
|
||||||
|
|
||||||
|
* Turn `AppComponent` into an application shell that only handles navigation
|
||||||
* 把`AppComponent`变成应用程序的“壳”,它只处理导航,
|
* 把`AppComponent`变成应用程序的“壳”,它只处理导航,
|
||||||
* relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`,
|
* Relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`
|
||||||
* 把现在由`AppComponent`关注的*英雄们*移到一个独立的`HeroesComponent`中,
|
* 把现在由`AppComponent`关注的*英雄们*移到一个独立的`HeroesComponent`中,
|
||||||
* add routing,
|
* Add routing
|
||||||
* 添加路由,
|
* 添加路由
|
||||||
* create a new `DashboardComponent`,
|
* Create a new `DashboardComponent`
|
||||||
* 添加一个新的`DashboardComponent`组件,
|
* 添加一个新的`DashboardComponent`组件
|
||||||
* tie the *Dashboard* into the navigation structure.
|
* Tie the *Dashboard* into the navigation structure
|
||||||
* 把*仪表盘*加入导航结构中。
|
* 把*仪表盘*加入导航结构中。
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
|
@ -137,15 +139,15 @@ code-example(language="bash").
|
||||||
`AppComponent`的职责已经被移交给`HeroesComponent`了。
|
`AppComponent`的职责已经被移交给`HeroesComponent`了。
|
||||||
与其把`AppComponent`中所有的东西都搬过去,不如索性把它改名为`HeroesComponent`,然后单独创建一个新的`AppComponent`壳。
|
与其把`AppComponent`中所有的东西都搬过去,不如索性把它改名为`HeroesComponent`,然后单独创建一个新的`AppComponent`壳。
|
||||||
|
|
||||||
The steps are:
|
The steps are to rename:
|
||||||
|
|
||||||
步骤如下:
|
改名的步骤如下:
|
||||||
* rename `app.component.ts` file to `heroes.component.ts`.
|
* `app.component.ts` file to `heroes.component.ts`
|
||||||
* 把`app.component.ts`文件改名为`heroes.component.ts`。
|
* 把`app.component.ts`文件改名为`heroes.component.ts`
|
||||||
* rename the `AppComponent` class to `HeroesComponent`.
|
* `AppComponent` class to `HeroesComponent`
|
||||||
* 把`AppComponent`类改名为`HeroesComponent`。
|
* 把`AppComponent`类改名为`HeroesComponent`
|
||||||
* rename the selector `my-app` to `my-heroes`.
|
* Selector `my-app` to `my-heroes`
|
||||||
* 把`my-app`选择器改名为`my-heroes`。
|
* 把`my-app`选择器改名为`my-heroes`
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'heroes-component-renaming', 'app/heroes.component.ts (showing renamings only)')(format=".")
|
+makeExample('toh-5/ts/app/heroes.component.ts', 'heroes-component-renaming', 'app/heroes.component.ts (showing renamings only)')(format=".")
|
||||||
|
@ -934,17 +936,15 @@ figure.image-display
|
||||||
1. *Set* the component metadata's `templateUrl` and `styleUrls` properties to refer to both files.
|
1. *Set* the component metadata's `templateUrl` and `styleUrls` properties to refer to both files.
|
||||||
1. *设置*组件元数据的`templateUrl`和`styleUrls`属性,来分别引用这两个文件。
|
1. *设置*组件元数据的`templateUrl`和`styleUrls`属性,来分别引用这两个文件。
|
||||||
|
|
||||||
We no longer display the `HeroDetailComponent` in the `HeroesComponent` template because we're navigating to it.
|
Because the template for `HeroesComponent` no longer uses `HeroDetailComponent`
|
||||||
So we can remove it from the metadata `directives` array. The `directives` array is now empty so we delete it.
|
directly — instead using the router to _navigate_ to it — we can
|
||||||
We might as well delete the `HeroDetailComponent` import statement too.
|
remove `HeroDetailComponent` from the directives list. That
|
||||||
|
list is now empty, so we can remove the `directives` property. The revised
|
||||||
|
`@Component` looks like this:
|
||||||
|
|
||||||
在`HeroesComponent`模板中,不需要再显示`HeroDetailComponent`,因为我们要导航到它。
|
由于`HeroesComponent`的模板中不再直接使用`HeroDetailComponent`,而是通过路由_导航_到它,
|
||||||
所以我们可以从元数据的`directives`数组中移除它。`directives`数组现在没东西了,因此我们也把它删掉。
|
于是我们就可以从`HeroDetailComponent`的指令列表中把它移除了。指令列表现在是空的,所以我们干脆把`directives`属性也移除。
|
||||||
我们也同样可以删掉`import` `HeroDetailComponent`的语句。
|
修改过的`@Component`看起来像这样:
|
||||||
|
|
||||||
The revised `@Component` looks like this:
|
|
||||||
|
|
||||||
修改过的`@Component`是这样的:
|
|
||||||
|
|
||||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'metadata', 'app/heroes.component.ts (revised metadata)')(format=".")
|
+makeExample('toh-5/ts/app/heroes.component.ts', 'metadata', 'app/heroes.component.ts (revised metadata)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
|
@ -1104,9 +1104,9 @@ figure.image-display
|
||||||
如果在根目录下没有一个名叫`styles.css`的文件,就添加它。
|
如果在根目录下没有一个名叫`styles.css`的文件,就添加它。
|
||||||
确保它包含[这里给出的主样式](!{styles_css})。
|
确保它包含[这里给出的主样式](!{styles_css})。
|
||||||
|
|
||||||
Also ensure this stylesheet is referenced in the traditional manner within `index.html`.
|
If necessary, also edit `index.html` to refer to this stylesheet.
|
||||||
|
|
||||||
同时确保这个样式表在`index.html`中被使用传统方式引用了。
|
如有必要,也可以编辑`index.html`来引用这个样式表。
|
||||||
|
|
||||||
+makeExample('toh-5/ts/index.html','css', 'index.html (link ref)')(format=".")
|
+makeExample('toh-5/ts/index.html','css', 'index.html (link ref)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
|
@ -1124,7 +1124,7 @@ figure.image-display
|
||||||
## 应用结构和代码
|
## 应用结构和代码
|
||||||
|
|
||||||
p.
|
p.
|
||||||
Review the sample source code in the #[+liveExampleLink2('', 'toh-5')] for this part.
|
Review the sample source code in the #[+liveExampleLink2('', 'toh-5')] for this chapter.
|
||||||
Verify that we have the following structure:
|
Verify that we have the following structure:
|
||||||
|
|
||||||
p.
|
p.
|
||||||
|
|
|
@ -51,6 +51,9 @@ module.exports = new Package('angular.io', [basePackage, targetPackage, cheatshe
|
||||||
'___esModule',
|
'___esModule',
|
||||||
'___core_private_types__',
|
'___core_private_types__',
|
||||||
'___platform_browser_private__',
|
'___platform_browser_private__',
|
||||||
|
'___platform_browser_private_types__',
|
||||||
|
'___platform_browser_dynamic_private__',
|
||||||
|
'___platform_browser_dynamic_private_types__',
|
||||||
'___compiler_private__',
|
'___compiler_private__',
|
||||||
'__core_private__',
|
'__core_private__',
|
||||||
'___core_private__'
|
'___core_private__'
|
||||||
|
|
Loading…
Reference in New Issue