* docs(toh-5): dashboard uses [routerLink] bindings #998 closes #998 * chore: temp add toh-5 to bad-code-excerpt-skip-patterns.txt
This commit is contained in:
parent
ae35f0e017
commit
fa99a8b0b2
|
@ -0,0 +1,9 @@
|
||||||
|
<!-- #docregion -->
|
||||||
|
<h3>Top Heroes</h3>
|
||||||
|
<div class="grid grid-pad">
|
||||||
|
<div *ngFor="let hero of heroes" class="col-1-4">
|
||||||
|
<div class="module hero">
|
||||||
|
<h4>{{hero.name}}</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,6 +1,12 @@
|
||||||
/* #docregion */
|
/* #docregion */
|
||||||
[class*='col-'] {
|
[class*='col-'] {
|
||||||
float: left;
|
float: left;
|
||||||
|
text-decoration: none;
|
||||||
|
padding-right: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
[class*='col-']:last-of-type {
|
||||||
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
*, *:after, *:before {
|
*, *:after, *:before {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
|
@ -10,12 +16,8 @@
|
||||||
h3 {
|
h3 {
|
||||||
text-align: center; margin-bottom: 0;
|
text-align: center; margin-bottom: 0;
|
||||||
}
|
}
|
||||||
[class*='col-'] {
|
h4 {
|
||||||
padding-right: 20px;
|
position: relative;
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
[class*='col-']:last-of-type {
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
}
|
||||||
.grid {
|
.grid {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -32,9 +34,6 @@ h3 {
|
||||||
background-color: #607D8B;
|
background-color: #607D8B;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
h4 {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.module:hover {
|
.module:hover {
|
||||||
background-color: #EEE;
|
background-color: #EEE;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
|
// #docregion imports
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:angular2/core.dart';
|
import 'package:angular2/core.dart';
|
||||||
// #docregion import-router
|
|
||||||
import 'package:angular2/router.dart';
|
|
||||||
// #enddocregion import-router
|
|
||||||
|
|
||||||
import 'hero.dart';
|
import 'hero.dart';
|
||||||
import 'hero_service.dart';
|
import 'hero_service.dart';
|
||||||
|
// #enddocregion imports
|
||||||
|
|
||||||
@Component(
|
@Component(
|
||||||
selector: 'my-dashboard',
|
selector: 'my-dashboard',
|
||||||
|
@ -24,24 +23,14 @@ class DashboardComponent implements OnInit {
|
||||||
List<Hero> heroes;
|
List<Hero> heroes;
|
||||||
|
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
final Router _router;
|
|
||||||
final HeroService _heroService;
|
final HeroService _heroService;
|
||||||
|
|
||||||
DashboardComponent(this._heroService, this._router);
|
DashboardComponent(this._heroService);
|
||||||
|
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
Future<Null> ngOnInit() async {
|
Future<Null> ngOnInit() async {
|
||||||
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
|
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// #docregion gotoDetail
|
|
||||||
void gotoDetail(Hero hero) {
|
|
||||||
var link = [
|
|
||||||
'HeroDetail',
|
|
||||||
{'id': hero.id.toString()}
|
|
||||||
];
|
|
||||||
_router.navigate(link);
|
|
||||||
}
|
|
||||||
// #enddocregion gotoDetail
|
|
||||||
}
|
}
|
||||||
|
// #enddocregion component
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
<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" >
|
<a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" 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>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
// #docplaster
|
|
||||||
// #docregion imports
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:angular2/core.dart';
|
|
||||||
|
|
||||||
import 'hero.dart';
|
|
||||||
import 'hero_service.dart';
|
|
||||||
// #enddocregion imports
|
|
||||||
|
|
||||||
// #docregion component
|
|
||||||
@Component(
|
|
||||||
selector: 'my-dashboard',
|
|
||||||
templateUrl: 'dashboard_component.html')
|
|
||||||
class DashboardComponent implements OnInit {
|
|
||||||
List<Hero> heroes;
|
|
||||||
final HeroService _heroService;
|
|
||||||
|
|
||||||
DashboardComponent(this._heroService);
|
|
||||||
|
|
||||||
Future<Null> ngOnInit() async {
|
|
||||||
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
gotoDetail(Hero hero) {/* not implemented yet */}
|
|
||||||
}
|
|
|
@ -42,16 +42,16 @@ describe('Tutorial part 5', () => {
|
||||||
beforeAll(() => browser.get(''));
|
beforeAll(() => browser.get(''));
|
||||||
|
|
||||||
function getPageElts() {
|
function getPageElts() {
|
||||||
let hrefElts = element.all(by.css('my-app a'));
|
let navElts = element.all(by.css('my-app nav a'));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hrefs: hrefElts,
|
navElts: navElts,
|
||||||
|
|
||||||
myDashboardHref: hrefElts.get(0),
|
myDashboardHref: navElts.get(0),
|
||||||
myDashboard: element(by.css('my-app my-dashboard')),
|
myDashboard: element(by.css('my-app my-dashboard')),
|
||||||
topHeroes: element.all(by.css('my-app my-dashboard > div h4')),
|
topHeroes: element.all(by.css('my-app my-dashboard > div h4')),
|
||||||
|
|
||||||
myHeroesHref: hrefElts.get(1),
|
myHeroesHref: navElts.get(1),
|
||||||
myHeroes: element(by.css('my-app my-heroes')),
|
myHeroes: element(by.css('my-app my-heroes')),
|
||||||
allHeroes: element.all(by.css('my-app my-heroes li')),
|
allHeroes: element.all(by.css('my-app my-heroes li')),
|
||||||
selectedHero: element(by.css('my-app li.selected')),
|
selectedHero: element(by.css('my-app li.selected')),
|
||||||
|
@ -73,7 +73,7 @@ describe('Tutorial part 5', () => {
|
||||||
|
|
||||||
const expectedViewNames = ['Dashboard', 'Heroes'];
|
const expectedViewNames = ['Dashboard', 'Heroes'];
|
||||||
it(`has views ${expectedViewNames}`, () => {
|
it(`has views ${expectedViewNames}`, () => {
|
||||||
let viewNames = getPageElts().hrefs.map((el: ElementFinder) => el.getText());
|
let viewNames = getPageElts().navElts.map((el: ElementFinder) => el.getText());
|
||||||
expect(viewNames).toEqual(expectedViewNames);
|
expect(viewNames).toEqual(expectedViewNames);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!-- #docregion -->
|
||||||
|
<h3>Top Heroes</h3>
|
||||||
|
<div class="grid grid-pad">
|
||||||
|
<div *ngFor="let hero of heroes" class="col-1-4">
|
||||||
|
<div class="module hero">
|
||||||
|
<h4>{{hero.name}}</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,27 +0,0 @@
|
||||||
// #docplaster
|
|
||||||
// #docregion imports
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
import { Hero } from './hero';
|
|
||||||
import { HeroService } from './hero.service';
|
|
||||||
// #enddocregion imports
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
moduleId: module.id,
|
|
||||||
selector: 'my-dashboard',
|
|
||||||
templateUrl: 'dashboard.component.html'
|
|
||||||
})
|
|
||||||
// #docregion component
|
|
||||||
export class DashboardComponent implements OnInit {
|
|
||||||
|
|
||||||
heroes: Hero[] = [];
|
|
||||||
|
|
||||||
constructor(private heroService: HeroService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.heroService.getHeroes()
|
|
||||||
.then(heroes => this.heroes = heroes.slice(1, 5));
|
|
||||||
}
|
|
||||||
|
|
||||||
gotoDetail(hero: Hero): void { /* not implemented yet */}
|
|
||||||
}
|
|
|
@ -1,6 +1,14 @@
|
||||||
/* #docregion */
|
/* #docregion */
|
||||||
[class*='col-'] {
|
[class*='col-'] {
|
||||||
float: left;
|
float: left;
|
||||||
|
padding-right: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
[class*='col-']:last-of-type {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
*, *:after, *:before {
|
*, *:after, *:before {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
|
@ -10,12 +18,8 @@
|
||||||
h3 {
|
h3 {
|
||||||
text-align: center; margin-bottom: 0;
|
text-align: center; margin-bottom: 0;
|
||||||
}
|
}
|
||||||
[class*='col-'] {
|
h4 {
|
||||||
padding-right: 20px;
|
position: relative;
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
[class*='col-']:last-of-type {
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
}
|
||||||
.grid {
|
.grid {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -32,9 +36,6 @@ h3 {
|
||||||
background-color: #607D8B;
|
background-color: #607D8B;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
h4 {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.module:hover {
|
.module:hover {
|
||||||
background-color: #EEE;
|
background-color: #EEE;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
<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">
|
<a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" 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>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
|
// #docregion imports
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
// #docregion import-router
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
// #enddocregion import-router
|
|
||||||
|
|
||||||
import { Hero } from './hero';
|
import { Hero } from './hero';
|
||||||
import { HeroService } from './hero.service';
|
import { HeroService } from './hero.service';
|
||||||
// #docregion metadata
|
// #enddocregion imports
|
||||||
|
|
||||||
|
// #docregion metadata
|
||||||
@Component({
|
@Component({
|
||||||
moduleId: module.id,
|
moduleId: module.id,
|
||||||
selector: 'my-dashboard',
|
selector: 'my-dashboard',
|
||||||
|
@ -19,27 +19,18 @@ import { HeroService } from './hero.service';
|
||||||
// #docregion metadata
|
// #docregion metadata
|
||||||
})
|
})
|
||||||
// #enddocregion metadata
|
// #enddocregion metadata
|
||||||
// #docregion component
|
// #docregion class
|
||||||
export class DashboardComponent implements OnInit {
|
export class DashboardComponent implements OnInit {
|
||||||
|
|
||||||
heroes: Hero[] = [];
|
heroes: Hero[] = [];
|
||||||
|
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
constructor(
|
constructor(private heroService: HeroService) { }
|
||||||
private router: Router,
|
|
||||||
private heroService: HeroService) {
|
|
||||||
}
|
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.heroService.getHeroes()
|
this.heroService.getHeroes()
|
||||||
.then(heroes => this.heroes = heroes.slice(1, 5));
|
.then(heroes => this.heroes = heroes.slice(1, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
// #docregion gotoDetail
|
|
||||||
gotoDetail(hero: Hero): void {
|
|
||||||
let link = ['/detail', hero.id];
|
|
||||||
this.router.navigate(link);
|
|
||||||
}
|
|
||||||
// #enddocregion gotoDetail
|
|
||||||
}
|
}
|
||||||
|
// #enddocregion class
|
||||||
|
|
|
@ -40,8 +40,10 @@ export class HeroesComponent implements OnInit {
|
||||||
this.selectedHero = hero;
|
this.selectedHero = hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #docregion gotoDetail
|
||||||
gotoDetail(): void {
|
gotoDetail(): void {
|
||||||
this.router.navigate(['/detail', this.selectedHero.id]);
|
this.router.navigate(['/detail', this.selectedHero.id]);
|
||||||
}
|
}
|
||||||
|
// #enddocregion gotoDetail
|
||||||
// #docregion renaming
|
// #docregion renaming
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
/* #docregion */
|
/* #docregion */
|
||||||
[class*='col-'] {
|
[class*='col-'] {
|
||||||
float: left;
|
float: left;
|
||||||
|
padding-right: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
[class*='col-']:last-of-type {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
*, *:after, *:before {
|
*, *:after, *:before {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
|
@ -10,12 +18,8 @@
|
||||||
h3 {
|
h3 {
|
||||||
text-align: center; margin-bottom: 0;
|
text-align: center; margin-bottom: 0;
|
||||||
}
|
}
|
||||||
[class*='col-'] {
|
h4 {
|
||||||
padding-right: 20px;
|
position: relative;
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
[class*='col-']:last-of-type {
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
}
|
||||||
.grid {
|
.grid {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -32,9 +36,6 @@ h3 {
|
||||||
background-color: #607D8B;
|
background-color: #607D8B;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
h4 {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.module:hover {
|
.module:hover {
|
||||||
background-color: #EEE;
|
background-color: #EEE;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -18,20 +18,11 @@ import 'hero_search_component.dart';
|
||||||
class DashboardComponent implements OnInit {
|
class DashboardComponent implements OnInit {
|
||||||
List<Hero> heroes;
|
List<Hero> heroes;
|
||||||
|
|
||||||
final Router _router;
|
|
||||||
final HeroService _heroService;
|
final HeroService _heroService;
|
||||||
|
|
||||||
DashboardComponent(this._heroService, this._router);
|
DashboardComponent(this._heroService);
|
||||||
|
|
||||||
Future<Null> ngOnInit() async {
|
Future<Null> ngOnInit() async {
|
||||||
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
|
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gotoDetail(Hero hero) {
|
|
||||||
var link = [
|
|
||||||
'HeroDetail',
|
|
||||||
{'id': hero.id.toString()}
|
|
||||||
];
|
|
||||||
_router.navigate(link);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<!-- #docregion -->
|
<!-- #docregion -->
|
||||||
<h3>Top Heroes</h3>
|
<h3>Top Heroes</h3>
|
||||||
<div class="grid grid-pad">
|
<div class="grid grid-pad">
|
||||||
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1-4">
|
<a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">
|
||||||
<div class="module hero">
|
<div class="module hero">
|
||||||
<h4>{{hero.name}}</h4>
|
<h4>{{hero.name}}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<hero-search></hero-search>
|
<hero-search></hero-search>
|
||||||
|
|
|
@ -48,16 +48,16 @@ describe('Tutorial part 6', () => {
|
||||||
beforeAll(() => browser.get(''));
|
beforeAll(() => browser.get(''));
|
||||||
|
|
||||||
function getPageElts() {
|
function getPageElts() {
|
||||||
let hrefElts = element.all(by.css('my-app a'));
|
let navElts = element.all(by.css('my-app nav a'));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hrefs: hrefElts,
|
navElts: navElts,
|
||||||
|
|
||||||
myDashboardHref: hrefElts.get(0),
|
myDashboardHref: navElts.get(0),
|
||||||
myDashboard: element(by.css('my-app my-dashboard')),
|
myDashboard: element(by.css('my-app my-dashboard')),
|
||||||
topHeroes: element.all(by.css('my-app my-dashboard > div h4')),
|
topHeroes: element.all(by.css('my-app my-dashboard > div h4')),
|
||||||
|
|
||||||
myHeroesHref: hrefElts.get(1),
|
myHeroesHref: navElts.get(1),
|
||||||
myHeroes: element(by.css('my-app my-heroes')),
|
myHeroes: element(by.css('my-app my-heroes')),
|
||||||
allHeroes: element.all(by.css('my-app my-heroes li')),
|
allHeroes: element.all(by.css('my-app my-heroes li')),
|
||||||
selectedHero: element(by.css('my-app li.selected')),
|
selectedHero: element(by.css('my-app li.selected')),
|
||||||
|
@ -82,7 +82,7 @@ describe('Tutorial part 6', () => {
|
||||||
|
|
||||||
const expectedViewNames = ['Dashboard', 'Heroes'];
|
const expectedViewNames = ['Dashboard', 'Heroes'];
|
||||||
it(`has views ${expectedViewNames}`, () => {
|
it(`has views ${expectedViewNames}`, () => {
|
||||||
let viewNames = getPageElts().hrefs.map((el: ElementFinder) => el.getText());
|
let viewNames = getPageElts().navElts.map((el: ElementFinder) => el.getText());
|
||||||
expect(viewNames).toEqual(expectedViewNames);
|
expect(viewNames).toEqual(expectedViewNames);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
/* #docplaster */
|
|
||||||
/* #docregion */
|
/* #docregion */
|
||||||
[class*='col-'] {
|
[class*='col-'] {
|
||||||
float: left;
|
float: left;
|
||||||
|
padding-right: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
[class*='col-']:last-of-type {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
*, *:after, *:before {
|
*, *:after, *:before {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
|
@ -11,12 +18,8 @@
|
||||||
h3 {
|
h3 {
|
||||||
text-align: center; margin-bottom: 0;
|
text-align: center; margin-bottom: 0;
|
||||||
}
|
}
|
||||||
[class*='col-'] {
|
h4 {
|
||||||
padding-right: 20px;
|
position: relative;
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
[class*='col-']:last-of-type {
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
}
|
||||||
.grid {
|
.grid {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -33,9 +36,6 @@ h3 {
|
||||||
background-color: #607D8B;
|
background-color: #607D8B;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
h4 {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.module:hover {
|
.module:hover {
|
||||||
background-color: #EEE;
|
background-color: #EEE;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -60,4 +60,3 @@ h4 {
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* #enddocregion */
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<!-- #docregion -->
|
<!-- #docregion -->
|
||||||
<h3>Top Heroes</h3>
|
<h3>Top Heroes</h3>
|
||||||
<div class="grid grid-pad">
|
<div class="grid grid-pad">
|
||||||
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1-4">
|
<a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">
|
||||||
<div class="module hero">
|
<div class="module hero">
|
||||||
<h4>{{hero.name}}</h4>
|
<h4>{{hero.name}}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<hero-search></hero-search>
|
<hero-search></hero-search>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// #docregion , search
|
// #docregion , search
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
import { Hero } from './hero';
|
import { Hero } from './hero';
|
||||||
import { HeroService } from './hero.service';
|
import { HeroService } from './hero.service';
|
||||||
|
@ -15,18 +14,10 @@ import { HeroService } from './hero.service';
|
||||||
export class DashboardComponent implements OnInit {
|
export class DashboardComponent implements OnInit {
|
||||||
heroes: Hero[] = [];
|
heroes: Hero[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(private heroService: HeroService) { }
|
||||||
private router: Router,
|
|
||||||
private heroService: HeroService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.heroService.getHeroes()
|
this.heroService.getHeroes()
|
||||||
.then(heroes => this.heroes = heroes.slice(1, 5));
|
.then(heroes => this.heroes = heroes.slice(1, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
gotoDetail(hero: Hero): void {
|
|
||||||
let link = ['/detail', hero.id];
|
|
||||||
this.router.navigate(link);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,16 +370,12 @@ block redirect-vs-use-as-default
|
||||||
:marked
|
:marked
|
||||||
Create that file with this content:
|
Create that file with this content:
|
||||||
|
|
||||||
+makeExcerpt('app/dashboard.component.html')
|
+makeExample('app/dashboard.component.1.html', '', 'app/dashboard.component.html')
|
||||||
|
|
||||||
: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.
|
||||||
|
|
||||||
There's a `(click)` binding to a `gotoDetail` method we haven't written yet and
|
|
||||||
we're displaying a list of heroes that we don't have.
|
|
||||||
We have work to do, starting with those heroes.
|
|
||||||
|
|
||||||
### Share the *HeroService*
|
### Share the *HeroService*
|
||||||
|
|
||||||
We'd like to re-use the `HeroService` to populate the component's `heroes` !{_array}.
|
We'd like to re-use the `HeroService` to populate the component's `heroes` !{_array}.
|
||||||
|
@ -394,12 +390,12 @@ block redirect-vs-use-as-default
|
||||||
|
|
||||||
Open <span ngio-ex>dashboard.component.ts</span> and add the requisite `import` statements.
|
Open <span ngio-ex>dashboard.component.ts</span> and add the requisite `import` statements.
|
||||||
|
|
||||||
+makeExcerpt('app/dashboard.component.2.ts','imports')
|
+makeExcerpt('app/dashboard.component.ts','imports')
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Now implement the `DashboardComponent` class like this:
|
Now implement the `DashboardComponent` class like this:
|
||||||
|
|
||||||
+makeExcerpt('app/dashboard.component.2.ts (class)', 'component')
|
+makeExcerpt('app/dashboard.component.ts (class)', 'class')
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
We've seen this kind of logic before in the `HeroesComponent`:
|
We've seen this kind of logic before in the `HeroesComponent`:
|
||||||
|
@ -408,8 +404,7 @@ block redirect-vs-use-as-default
|
||||||
* Inject the `HeroService` in the constructor and hold it in a private `!{_priv}heroService` field.
|
* Inject the `HeroService` in the constructor and hold it in a private `!{_priv}heroService` field.
|
||||||
* Call the service to get heroes inside the Angular `ngOnInit` lifecycle hook.
|
* Call the service to get heroes inside the Angular `ngOnInit` lifecycle hook.
|
||||||
|
|
||||||
The noteworthy differences: we cherry-pick four heroes (2nd, 3rd, 4th, and 5th)
|
In this dashboard we cherry-pick four heroes (2nd, 3rd, 4th, and 5th) with the `Array.slice` method.
|
||||||
and stub the `gotoDetail` method until we're ready to implement it.
|
|
||||||
|
|
||||||
Refresh the browser and see four heroes in the new dashboard.
|
Refresh the browser and see four heroes in the new dashboard.
|
||||||
|
|
||||||
|
@ -580,7 +575,7 @@ block extract-id
|
||||||
incremental improvement and migrate the template to its own file,
|
incremental improvement and migrate the template to its own file,
|
||||||
called <span ngio-ex>hero-detail.component.html</span>:
|
called <span ngio-ex>hero-detail.component.html</span>:
|
||||||
|
|
||||||
+makeExample('app/hero-detail.component.html')
|
+makeExample('app/hero-detail.component.html')(format='.')
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
We update the component metadata with a `moduleId` and a `templateUrl` pointing to the template file that we just created.
|
We update the component metadata with a `moduleId` and a `templateUrl` pointing to the template file that we just created.
|
||||||
|
@ -596,32 +591,26 @@ block extract-id
|
||||||
|
|
||||||
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.
|
Although the dashboard heroes are presented as button-like blocks, they should behave like anchor tags.
|
||||||
|
When hovering over a hero block, the target URL should display in the browser status bar
|
||||||
|
and the user should be able to copy the link or open the hero detail view in a new tab.
|
||||||
|
|
||||||
+makeExcerpt('app/dashboard.component.html', 'click')
|
To achieve this effect, reopen the `dashboard.component.html` and replace the repeated `<div *ngFor...>` tags
|
||||||
|
with `<a>` tags. The opening `<a>` tag looks like this:
|
||||||
|
|
||||||
:marked
|
+makeExample('app/dashboard.component.html', 'click', 'app/dashboard.component.html (repeated <a> tag)')
|
||||||
We stubbed the `gotoDetail` method when we rewrote the `DashboardComponent`.
|
|
||||||
Now we give it a real implementation.
|
|
||||||
|
|
||||||
+makeExcerpt('app/dashboard.component.ts','gotoDetail')
|
|
||||||
|
|
||||||
- var _pathVsName = _docsFor == 'dart' ? 'name' : 'path'
|
- var _pathVsName = _docsFor == 'dart' ? 'name' : 'path'
|
||||||
:marked
|
:marked
|
||||||
The `gotoDetail` method navigates in two steps:
|
Notice the `[routerLink]` binding.
|
||||||
|
|
||||||
1. Set a route *link parameters !{_array}*
|
In the top level navigation in the [`AppComponent`
|
||||||
1. Pass the !{_array} to the router's navigate method
|
template](#router-links) has router links set to fixed !{_pathVsName}s of the
|
||||||
|
destination routes, "/dashboard" and "/heroes".
|
||||||
|
|
||||||
For navigation, we wrote router links <span if-docs="dart">as *link
|
This time, we're binding to an expression containing a **link parameters !{_array}**.
|
||||||
parameters !{_array}s*</span> in the [`AppComponent`
|
The !{_array} has two elements, the ***!{_pathVsName}*** of
|
||||||
template](#router-links). Those link<span if-docs="dart"> parameters
|
the destination route and a ***route parameter*** set to the value of the current hero's `id`.
|
||||||
!{_array}</span>s had only one element, the !{_pathVsName} of the
|
|
||||||
destination route.
|
|
||||||
|
|
||||||
This link parameters !{_array} has two elements, the ***!{_pathVsName}*** of
|
|
||||||
the destination route and a ***route parameter*** <span if-docs="dart">with
|
|
||||||
an `id` field</span> set to the value of the selected hero's `id`.
|
|
||||||
|
|
||||||
The two !{_array} items align with the ***!{_pathVsName}*** and ***:id***
|
The two !{_array} items align with the ***!{_pathVsName}*** and ***:id***
|
||||||
token in the parameterized hero detail route definition we added to
|
token in the parameterized hero detail route definition we added to
|
||||||
|
@ -630,14 +619,6 @@ block extract-id
|
||||||
- var _file = _docsFor == 'dart' ? 'app/app.component.ts' : 'app/app.module.3.ts'
|
- var _file = _docsFor == 'dart' ? 'app/app.component.ts' : 'app/app.module.3.ts'
|
||||||
+makeExcerpt(_file + ' (hero detail)', 'hero-detail')
|
+makeExcerpt(_file + ' (hero detail)', 'hero-detail')
|
||||||
|
|
||||||
:marked
|
|
||||||
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`):
|
|
||||||
|
|
||||||
+makeExcerpt('app/dashboard.component.ts ()','import-router', '')
|
|
||||||
|
|
||||||
+makeExcerpt('app/dashboard.component.ts', 'ctor', '')
|
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Refresh the browser and select a hero from the dashboard; the app should navigate directly to that hero’s details.
|
Refresh the browser and select a hero from the dashboard; the app should navigate directly to that hero’s details.
|
||||||
|
|
||||||
|
@ -703,14 +684,14 @@ block extract-id
|
||||||
:marked
|
:marked
|
||||||
Our goal is to move the detail to its own view and navigate to it when the user decides to edit a selected hero.
|
Our goal is to move the detail to its own view and navigate to it when the user decides to edit a selected hero.
|
||||||
|
|
||||||
Delete the `<h1>` at the top (forgot about it during the `AppComponent`-to-`HeroesComponent` conversion).
|
Delete the `<h1>` at the top (we forgot about it during the `AppComponent`-to-`HeroesComponent` conversion).
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
We'll no longer show the full `HeroDetailComponent` here.
|
We'll no longer show the full `HeroDetailComponent` here.
|
||||||
We're going to display the hero detail on its own page and route to it as we did in the dashboard.
|
We're going to display the hero detail on its own page and route to it as we did in the dashboard.
|
||||||
|
|
||||||
But we'll throw in a small twist for variety.
|
We'll throw in a small twist for variety.
|
||||||
We are keeping the "master/detail" style but shrinking the detail to a "mini", read-only version.
|
We are keeping the "master/detail" style but shrinking the detail to a "mini", read-only version.
|
||||||
When the user selects a hero from the list, we *don't* go to the detail page.
|
When the user selects a hero from the list, we *don't* go to the detail page.
|
||||||
We show a *mini-detail* on *this* page instead and make the user click a button to navigate to the *full detail *page.
|
We show a *mini-detail* on *this* page instead and make the user click a button to navigate to the *full detail *page.
|
||||||
|
@ -770,15 +751,25 @@ block heroes-component-cleanup
|
||||||
+makeExcerpt('app/heroes.component.ts (revised metadata)', 'metadata')
|
+makeExcerpt('app/heroes.component.ts (revised metadata)', 'metadata')
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Now we can see what's going on as we update the component class along the same lines as the dashboard:
|
### Update the _HeroesComponent_ class.
|
||||||
|
|
||||||
1. Import the `router`
|
The `HeroesComponent` navigates to the `HeroesDetailComponent` in response to a button click.
|
||||||
|
The button's _click_ event is bound to a `gotoDetail` method that navigates _imperatively_
|
||||||
|
by telling the router where to go.
|
||||||
|
|
||||||
|
This approach requires some changes to the component class:
|
||||||
|
|
||||||
|
1. Import the `router` from the Angular router library
|
||||||
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 `gotoDetail` by calling the `router.navigate` method
|
||||||
|
|
||||||
with a two-part hero-detail link parameters !{_array}.
|
+makeExcerpt('app/heroes.component.ts', 'gotoDetail')
|
||||||
|
:marked
|
||||||
Here's the revised component class:
|
Note that we're passing a two-element **link parameters !{_array}**
|
||||||
|
— a path and the route parameter — to
|
||||||
|
the `router.navigate` method just as we did in the `[routerLink]` binding
|
||||||
|
back in the `DashboardComponent`
|
||||||
|
Here's the fully revised `HeroesComponent` class:
|
||||||
|
|
||||||
+makeExcerpt('app/heroes.component.ts', 'class')
|
+makeExcerpt('app/heroes.component.ts', 'class')
|
||||||
|
|
||||||
|
|
|
@ -5,3 +5,4 @@
|
||||||
/ts/latest/guide/style-guide.html # https://github.com/angular/angular.io/issues/2123
|
/ts/latest/guide/style-guide.html # https://github.com/angular/angular.io/issues/2123
|
||||||
/ts/latest/guide/upgrade.html # In a transient state until RC6 - @filipe.silva
|
/ts/latest/guide/upgrade.html # In a transient state until RC6 - @filipe.silva
|
||||||
/[jt]s/.*/api/forms/index/NG_VALIDATORS-let.html # RC6 contains broken example tags
|
/[jt]s/.*/api/forms/index/NG_VALIDATORS-let.html # RC6 contains broken example tags
|
||||||
|
/dart/latest/tutorial/toh-pt5.html
|
||||||
|
|
Loading…
Reference in New Issue