From bacc4bcbac3014323ee0bb45abe03becf9d232eb Mon Sep 17 00:00:00 2001
From: Patrice Chalin
Date: Tue, 28 Jun 2016 08:16:59 -0700
Subject: [PATCH 01/31] docs(guide/{di,ts,toh-[23]}): follow-up to #1654
(#1767)
Mainly Dart-side review, following #1654.
dependency-injection:
- Renamed components in providers_component.dart
- E2e suites passed:
- public/docs/_examples/dependency-injection/dart
- public/docs/_examples/dependency-injection/ts
template-syntax:
- Removed unused global variable.
- Suites passed:
public/docs/_examples/template-syntax/dart
public/docs/_examples/template-syntax/ts
toh-2 & 3:
- Clean-up.
---
.../dart/lib/providers_component.dart | 71 +++++++++----------
.../dart/lib/hero_detail_component.dart | 2 -
.../toh-2/dart/lib/app_component.dart | 30 ++++----
.../toh-3/dart/lib/app_component.dart | 26 +++----
4 files changed, 63 insertions(+), 66 deletions(-)
diff --git a/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart b/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart
index a52ea6d267..08c9e542a8 100644
--- a/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart
+++ b/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart
@@ -18,10 +18,10 @@ const template = '{{log}}';
providers: const [Logger]
// #enddocregion providers-1, providers-logger
)
-class ProviderComponent1 {
+class Provider1Component {
String log;
- ProviderComponent1(Logger logger) {
+ Provider1Component(Logger logger) {
logger.log('Hello from logger provided with Logger class');
log = logger.logs[0];
}
@@ -31,15 +31,15 @@ class ProviderComponent1 {
@Component(
selector: 'provider-3',
template: '{{log}}',
- providers:
+ providers:
// #docregion providers-3
const [const Provider(Logger, useClass: Logger)]
// #enddocregion providers-3
)
-class ProviderComponent3 {
+class Provider3Component {
String log;
- ProviderComponent3(Logger logger) {
+ Provider3Component(Logger logger) {
logger.log('Hello from logger provided with useClass:Logger');
log = logger.logs[0];
}
@@ -56,10 +56,10 @@ class BetterLogger extends Logger {}
const [const Provider(Logger, useClass: BetterLogger)]
// #enddocregion providers-4
)
-class ProviderComponent4 {
+class Provider4Component {
String log;
- ProviderComponent4(Logger logger) {
+ Provider4Component(Logger logger) {
logger.log('Hello from logger provided with useClass:BetterLogger');
log = logger.logs[0];
}
@@ -87,10 +87,10 @@ class EvenBetterLogger extends Logger {
const [UserService, const Provider(Logger, useClass: EvenBetterLogger)]
// #enddocregion providers-5
)
-class ProviderComponent5 {
+class Provider5Component {
String log;
- ProviderComponent5(Logger logger) {
+ Provider5Component(Logger logger) {
logger.log('Hello from EvenBetterlogger');
log = logger.logs[0];
}
@@ -116,10 +116,10 @@ class OldLogger extends Logger {
const Provider(OldLogger, useClass: NewLogger)]
// #enddocregion providers-6a
)
-class ProviderComponent6a {
+class Provider6aComponent {
String log;
- ProviderComponent6a(NewLogger newLogger, OldLogger oldLogger) {
+ Provider6aComponent(NewLogger newLogger, OldLogger oldLogger) {
if (newLogger == oldLogger) {
throw new Exception('expected the two loggers to be different instances');
}
@@ -140,10 +140,10 @@ class ProviderComponent6a {
const Provider(OldLogger, useExisting: NewLogger)]
// #enddocregion providers-6b
)
-class ProviderComponent6b {
+class Provider6bComponent {
String log;
- ProviderComponent6b(NewLogger newLogger, OldLogger oldLogger) {
+ Provider6bComponent(NewLogger newLogger, OldLogger oldLogger) {
if (newLogger != oldLogger) {
throw new Exception('expected the two loggers to be the same instance');
}
@@ -178,10 +178,10 @@ const silentLogger = const SilentLogger();
const [const Provider(Logger, useValue: silentLogger)]
// #enddocregion providers-7
)
-class ProviderComponent7 {
+class Provider7Component {
String log;
- ProviderComponent7(Logger logger) {
+ Provider7Component(Logger logger) {
logger.log('Hello from logger provided with useValue');
log = logger.logs[0];
}
@@ -191,13 +191,13 @@ class ProviderComponent7 {
selector: 'provider-8',
template: '{{log}}',
providers: const [heroServiceProvider, Logger, UserService])
-class ProviderComponent8 {
- // #docregion provider-8-ctor
- ProviderComponent8(HeroService heroService);
- // #enddocregion provider-8-ctor
-
+class Provider8Component {
// must be true else this component would have blown up at runtime
var log = 'Hero service injected successfully via heroServiceProvider';
+
+ // #docregion provider-8-ctor
+ Provider8Component(HeroService heroService);
+ // #enddocregion provider-8-ctor
}
@Component(
@@ -208,12 +208,12 @@ class ProviderComponent8 {
const Provider(APP_CONFIG, useValue: heroDiConfig)]
// #enddocregion providers-9
)
-class ProviderComponent9 implements OnInit {
+class Provider9Component implements OnInit {
Map _config;
String log;
// #docregion provider-9-ctor
- ProviderComponent9(@Inject(APP_CONFIG) this._config);
+ Provider9Component(@Inject(APP_CONFIG) this._config);
// #enddocregion provider-9-ctor
@override
@@ -225,7 +225,7 @@ class ProviderComponent9 implements OnInit {
// Sample providers 1 to 7 illustrate a required logger dependency.
// Optional logger, can be null.
@Component(selector: 'provider-10', template: '{{log}}')
-class ProviderComponent10 implements OnInit {
+class Provider10Component implements OnInit {
final Logger _logger;
String log;
@@ -234,11 +234,10 @@ class ProviderComponent10 implements OnInit {
HeroService(@Optional() this._logger) {
// #enddocregion provider-10-ctor
*/
- ProviderComponent10(@Optional() this._logger) {
+ Provider10Component(@Optional() this._logger) {
const someMessage = 'Hello from the injected logger';
// #docregion provider-10-ctor
- if (_logger != null)
- _logger.log(someMessage);
+ _logger?.log(someMessage);
}
// #enddocregion provider-10-ctor
@@ -263,15 +262,15 @@ class ProviderComponent10 implements OnInit {
''',
directives: const [
- ProviderComponent1,
- ProviderComponent3,
- ProviderComponent4,
- ProviderComponent5,
- ProviderComponent6a,
- ProviderComponent6b,
- ProviderComponent7,
- ProviderComponent8,
- ProviderComponent9,
- ProviderComponent10
+ Provider1Component,
+ Provider3Component,
+ Provider4Component,
+ Provider5Component,
+ Provider6aComponent,
+ Provider6bComponent,
+ Provider7Component,
+ Provider8Component,
+ Provider9Component,
+ Provider10Component
])
class ProvidersComponent {}
diff --git a/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart b/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart
index 5fd0b1e3cf..5eb6da1c76 100644
--- a/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart
+++ b/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart
@@ -4,8 +4,6 @@ import 'package:angular2/core.dart';
import 'hero.dart';
-var nextHeroDetailId = 1;
-
// #docregion input-output-2
@Component(
// #enddocregion input-output-2
diff --git a/public/docs/_examples/toh-2/dart/lib/app_component.dart b/public/docs/_examples/toh-2/dart/lib/app_component.dart
index 66268118dc..82fc56754a 100644
--- a/public/docs/_examples/toh-2/dart/lib/app_component.dart
+++ b/public/docs/_examples/toh-2/dart/lib/app_component.dart
@@ -8,6 +8,21 @@ class Hero {
Hero(this.id, this.name);
}
+// #docregion hero-array
+final List mockHeroes = [
+ new Hero(11, 'Mr. Nice'),
+ new Hero(12, 'Narco'),
+ new Hero(13, 'Bombasto'),
+ new Hero(14, 'Celeritas'),
+ new Hero(15, 'Magneta'),
+ new Hero(16, 'RubberMan'),
+ new Hero(17, 'Dynama'),
+ new Hero(18, 'Dr IQ'),
+ new Hero(19, 'Magma'),
+ new Hero(20, 'Tornado')
+];
+// #enddocregion hero-array
+
@Component(
selector: 'my-app',
template: '''
@@ -94,18 +109,3 @@ class AppComponent {
}
// #enddocregion on-select
}
-// #enddocregion
-
-// #docregion hero-array
-final List mockHeroes = [
- new Hero(11, 'Mr. Nice'),
- new Hero(12, 'Narco'),
- new Hero(13, 'Bombasto'),
- new Hero(14, 'Celeritas'),
- new Hero(15, 'Magneta'),
- new Hero(16, 'RubberMan'),
- new Hero(17, 'Dynama'),
- new Hero(18, 'Dr IQ'),
- new Hero(19, 'Magma'),
- new Hero(20, 'Tornado')
-];
diff --git a/public/docs/_examples/toh-3/dart/lib/app_component.dart b/public/docs/_examples/toh-3/dart/lib/app_component.dart
index d2ed99d75b..a51d317005 100644
--- a/public/docs/_examples/toh-3/dart/lib/app_component.dart
+++ b/public/docs/_examples/toh-3/dart/lib/app_component.dart
@@ -8,6 +8,19 @@ import 'hero.dart';
import 'hero_detail_component.dart';
// #enddocregion hero-detail-import
+final List mockHeroes = [
+ new Hero(11, 'Mr. Nice'),
+ new Hero(12, 'Narco'),
+ new Hero(13, 'Bombasto'),
+ new Hero(14, 'Celeritas'),
+ new Hero(15, 'Magneta'),
+ new Hero(16, 'RubberMan'),
+ new Hero(17, 'Dynama'),
+ new Hero(18, 'Dr IQ'),
+ new Hero(19, 'Magma'),
+ new Hero(20, 'Tornado')
+];
+
@Component(
selector: 'my-app',
// #docregion hero-detail-template
@@ -87,16 +100,3 @@ class AppComponent {
selectedHero = hero;
}
}
-
-final List mockHeroes = [
- new Hero(11, 'Mr. Nice'),
- new Hero(12, 'Narco'),
- new Hero(13, 'Bombasto'),
- new Hero(14, 'Celeritas'),
- new Hero(15, 'Magneta'),
- new Hero(16, 'RubberMan'),
- new Hero(17, 'Dynama'),
- new Hero(18, 'Dr IQ'),
- new Hero(19, 'Magma'),
- new Hero(20, 'Tornado')
-];
From 3510f96620085c2fd3e12e831b9b15663946fd58 Mon Sep 17 00:00:00 2001
From: Patrice Chalin
Date: Tue, 28 Jun 2016 08:22:53 -0700
Subject: [PATCH 02/31] docs(guide/pipes): follow-up to #1654 (#1769)
Mainly Dart-side review, following #1654:
- Updates to follow style guide
- Suites passed:
public/docs/_examples/pipes/dart
- Suites failed (known issue - #1761):
public/docs/_examples/pipes/ts
---
public/docs/_examples/pipes/dart/lib/app_component.dart | 8 ++++----
.../pipes/dart/lib/hero_birthday1_component.dart | 2 +-
.../pipes/dart/lib/hero_birthday2_component.dart | 2 +-
.../pipes/dart/lib/power_boost_calculator_component.dart | 2 +-
.../_examples/pipes/dart/lib/power_booster_component.dart | 2 +-
public/docs/_examples/pipes/dart/web/main.dart | 2 +-
6 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/public/docs/_examples/pipes/dart/lib/app_component.dart b/public/docs/_examples/pipes/dart/lib/app_component.dart
index 85b32279a2..a03bb4a460 100644
--- a/public/docs/_examples/pipes/dart/lib/app_component.dart
+++ b/public/docs/_examples/pipes/dart/lib/app_component.dart
@@ -16,11 +16,11 @@ import 'power_booster_component.dart';
FlyingHeroesComponent,
FlyingHeroesImpureComponent,
HeroAsyncMessageComponent,
- HeroBirthday,
- HeroBirthday2,
+ HeroBirthdayComponent,
+ HeroBirthday2Component,
HeroListComponent,
- PowerBoostCalculator,
- PowerBooster,
+ PowerBoostCalculatorComponent,
+ PowerBoosterComponent,
])
class AppComponent {
DateTime birthday = new DateTime(1988, 4, 15); // April 15, 1988
diff --git a/public/docs/_examples/pipes/dart/lib/hero_birthday1_component.dart b/public/docs/_examples/pipes/dart/lib/hero_birthday1_component.dart
index accb756c37..2d2b63bb15 100644
--- a/public/docs/_examples/pipes/dart/lib/hero_birthday1_component.dart
+++ b/public/docs/_examples/pipes/dart/lib/hero_birthday1_component.dart
@@ -7,6 +7,6 @@ import 'package:angular2/angular2.dart';
template: "The hero's birthday is {{ birthday | date }}
"
// #enddocregion hero-birthday-template
)
-class HeroBirthday {
+class HeroBirthdayComponent {
DateTime birthday = new DateTime(1988, 4, 15); // April 15, 1988
}
diff --git a/public/docs/_examples/pipes/dart/lib/hero_birthday2_component.dart b/public/docs/_examples/pipes/dart/lib/hero_birthday2_component.dart
index eb76d84859..393a78bccb 100644
--- a/public/docs/_examples/pipes/dart/lib/hero_birthday2_component.dart
+++ b/public/docs/_examples/pipes/dart/lib/hero_birthday2_component.dart
@@ -11,7 +11,7 @@ import 'package:angular2/angular2.dart';
// #enddocregion template
)
// #docregion class
-class HeroBirthday2 {
+class HeroBirthday2Component {
DateTime birthday = new DateTime(1988, 4, 15); // April 15, 1988
bool toggle = true;
diff --git a/public/docs/_examples/pipes/dart/lib/power_boost_calculator_component.dart b/public/docs/_examples/pipes/dart/lib/power_boost_calculator_component.dart
index 7c726ce511..1bf00b31fe 100644
--- a/public/docs/_examples/pipes/dart/lib/power_boost_calculator_component.dart
+++ b/public/docs/_examples/pipes/dart/lib/power_boost_calculator_component.dart
@@ -13,7 +13,7 @@ import 'exponential_strength_pipe.dart';
''',
pipes: const [ExponentialStrengthPipe])
-class PowerBoostCalculator {
+class PowerBoostCalculatorComponent {
num power = 5;
num factor = 1;
}
diff --git a/public/docs/_examples/pipes/dart/lib/power_booster_component.dart b/public/docs/_examples/pipes/dart/lib/power_booster_component.dart
index 9152a2cc52..41a7be9878 100644
--- a/public/docs/_examples/pipes/dart/lib/power_booster_component.dart
+++ b/public/docs/_examples/pipes/dart/lib/power_booster_component.dart
@@ -9,4 +9,4 @@ import 'exponential_strength_pipe.dart';
Super power boost: {{2 | exponentialStrength: 10}}
''',
pipes: const [ExponentialStrengthPipe])
-class PowerBooster {}
+class PowerBoosterComponent {}
diff --git a/public/docs/_examples/pipes/dart/web/main.dart b/public/docs/_examples/pipes/dart/web/main.dart
index 98e9c1b34b..3266c05644 100644
--- a/public/docs/_examples/pipes/dart/web/main.dart
+++ b/public/docs/_examples/pipes/dart/web/main.dart
@@ -5,5 +5,5 @@ import 'package:pipe_examples/hero_birthday1_component.dart';
main() {
bootstrap(AppComponent);
- bootstrap(HeroBirthday);
+ bootstrap(HeroBirthdayComponent);
}
From 283195685f408c0b01bbba886f3365f7f4895003 Mon Sep 17 00:00:00 2001
From: Patrice Chalin
Date: Tue, 28 Jun 2016 08:25:12 -0700
Subject: [PATCH 03/31] docs(guide/user-input): follow-up to #1654 (#1770)
Mainly Dart-side review, following #1654:
- Updates to follow style guide
- Suites passed:
public/docs/_examples/user-input/dart
public/docs/_examples/user-input/ts
Note: the click-me2 component is not mentioned in the prose, maybe it
should be.
---
.../user-input/dart/lib/app_component.dart | 4 ++--
.../dart/lib/click_me2_component.dart | 18 ++++++++++++++++++
.../dart/lib/click_me_component.dart | 15 +++++++++------
.../dart/lib/click_me_component_2.dart | 17 -----------------
4 files changed, 29 insertions(+), 25 deletions(-)
create mode 100644 public/docs/_examples/user-input/dart/lib/click_me2_component.dart
delete mode 100644 public/docs/_examples/user-input/dart/lib/click_me_component_2.dart
diff --git a/public/docs/_examples/user-input/dart/lib/app_component.dart b/public/docs/_examples/user-input/dart/lib/app_component.dart
index d86db43cb0..5f2c86f8d9 100644
--- a/public/docs/_examples/user-input/dart/lib/app_component.dart
+++ b/public/docs/_examples/user-input/dart/lib/app_component.dart
@@ -2,7 +2,7 @@
import 'package:angular2/core.dart';
import 'click_me_component.dart';
-import 'click_me_component_2.dart';
+import 'click_me2_component.dart';
import 'keyup_components.dart';
import 'little_tour_component.dart';
import 'loop_back_component.dart';
@@ -12,7 +12,7 @@ import 'loop_back_component.dart';
templateUrl: 'app_component.html',
directives: const [
ClickMeComponent,
- ClickMeComponent2,
+ ClickMe2Component,
KeyUpComponentV1,
KeyUpComponentV2,
KeyUpComponentV3,
diff --git a/public/docs/_examples/user-input/dart/lib/click_me2_component.dart b/public/docs/_examples/user-input/dart/lib/click_me2_component.dart
new file mode 100644
index 0000000000..3329a6692e
--- /dev/null
+++ b/public/docs/_examples/user-input/dart/lib/click_me2_component.dart
@@ -0,0 +1,18 @@
+// #docregion
+import 'package:angular2/core.dart';
+
+@Component(
+ selector: 'click-me2',
+ template: '''
+ No! .. Click me!
+ {{clickMessage}}''')
+class ClickMe2Component {
+ String clickMessage = '';
+ int _clicks = 1;
+
+ void onClickMe2(dynamic event) {
+ var evtMsg =
+ event != null ? ' Event target is ' + event.target.tagName : '';
+ clickMessage = ('Click #${_clicks++}. ${evtMsg}');
+ }
+}
diff --git a/public/docs/_examples/user-input/dart/lib/click_me_component.dart b/public/docs/_examples/user-input/dart/lib/click_me_component.dart
index c1c7e19f93..c31d92e78b 100644
--- a/public/docs/_examples/user-input/dart/lib/click_me_component.dart
+++ b/public/docs/_examples/user-input/dart/lib/click_me_component.dart
@@ -1,3 +1,9 @@
+/* FOR DOCS ... MUST MATCH ClickMeComponent template
+// #docregion click-me-button
+ Click me!
+// #enddocregion click-me-button
+*/
+
// #docregion
import 'package:angular2/core.dart';
@@ -5,15 +11,12 @@ import 'package:angular2/core.dart';
@Component(
selector: 'click-me',
template: '''
- // #docregion click-me-button
- Click me!
- // #enddocregion click-me-button
- {{clickMessage}}''')
+ Click me!
+ {{clickMessage}}''')
class ClickMeComponent {
String clickMessage = '';
- onClickMe() {
+ void onClickMe() {
clickMessage = 'You are my hero!';
}
}
-// #enddocregion click-me-component
diff --git a/public/docs/_examples/user-input/dart/lib/click_me_component_2.dart b/public/docs/_examples/user-input/dart/lib/click_me_component_2.dart
deleted file mode 100644
index 8047b2280a..0000000000
--- a/public/docs/_examples/user-input/dart/lib/click_me_component_2.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// #docregion
-import 'package:angular2/core.dart';
-
-@Component(
- selector: 'click-me2',
- template: '''No! .. Click me!
- {{clickMessage}}''')
-class ClickMeComponent2 {
- String clickMessage = '';
- int clicks = 1;
-
- onClickMe2(dynamic event) {
- var evtMsg =
- event != null ? ' Event target is ' + event.target.tagName : '';
- clickMessage = ('Click #${clicks++}. ${evtMsg}');
- }
-}
From 2480a9157060b0852dfde7e7d048a75328f9cee3 Mon Sep 17 00:00:00 2001
From: Naomi Black
Date: Tue, 28 Jun 2016 11:37:53 -0700
Subject: [PATCH 04/31] chore(api): remove internal compiler API from docgen
closes #1771
---
tools/api-builder/angular.io-package/index.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/tools/api-builder/angular.io-package/index.js b/tools/api-builder/angular.io-package/index.js
index 60a801057d..11ffe8cb17 100644
--- a/tools/api-builder/angular.io-package/index.js
+++ b/tools/api-builder/angular.io-package/index.js
@@ -62,8 +62,6 @@ module.exports = new Package('angular.io', [basePackage, targetPackage, cheatshe
readTypeScriptModules.sourceFiles = [
'@angular/common/index.ts',
'@angular/common/testing.ts',
- '@angular/compiler/index.ts',
- '@angular/compiler/testing.ts',
'@angular/core/index.ts',
'@angular/core/testing.ts',
'@angular/http/index.ts',
From c380d69ea1f4dd78ac79b8c4e1e849346c79f679 Mon Sep 17 00:00:00 2001
From: Foxandxss
Date: Tue, 28 Jun 2016 15:48:15 +0200
Subject: [PATCH 05/31] chore: lock router-deprecated to rc.2 for plunkers
---
public/docs/_examples/systemjs.config.plunker.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/public/docs/_examples/systemjs.config.plunker.js b/public/docs/_examples/systemjs.config.plunker.js
index 40758797e6..a9ec367c33 100644
--- a/public/docs/_examples/systemjs.config.plunker.js
+++ b/public/docs/_examples/systemjs.config.plunker.js
@@ -8,6 +8,7 @@
var ngVer = '@2.0.0-rc.3'; // lock in the angular package version; do not let it float to current!
var routerVer = '@3.0.0-alpha.7'; // lock router version
var formsVer = '@0.1.1'; // lock forms version
+ var routerDeprecatedVer = '@2.0.0-rc.2'; // temporarily until we update all the guides
//map tells the System loader where to look for things
var map = {
@@ -16,6 +17,7 @@
'@angular': 'https://npmcdn.com/@angular', // sufficient if we didn't pin the version
'@angular/router': 'https://npmcdn.com/@angular/router' + routerVer,
'@angular/forms': 'https://npmcdn.com/@angular/forms' + formsVer,
+ '@angular/router-deprecated': 'https://npmcdn.com/@angular/router-deprecated' + routerDeprecatedVer,
'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest
'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6',
'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js',
@@ -36,7 +38,6 @@
'http',
'platform-browser',
'platform-browser-dynamic',
- 'router-deprecated',
'upgrade',
];
@@ -62,6 +63,9 @@
// Forms not on rc yet
packages['@angular/forms'] = { main: 'index.js', defaultExtension: 'js' };
+ // Temporarily until we update the guides
+ packages['@angular/router-deprecated'] = { main: '/bundles/router-deprecated' + '.umd.js', defaultExtension: 'js' };
+
var config = {
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
transpiler: 'ts',
From c02b942008b1a6e59ead4e3a513324ef72938963 Mon Sep 17 00:00:00 2001
From: Foxandxss
Date: Mon, 27 Jun 2016 19:29:37 +0200
Subject: [PATCH 06/31] chore: update to router alpha.8
---
public/docs/_examples/package.json | 2 +-
public/docs/_examples/quickstart/js/package.1.json | 2 +-
public/docs/_examples/quickstart/ts/package.1.json | 2 +-
public/docs/_examples/webpack/ts/package.webpack.json | 2 +-
public/docs/_examples/webpack/ts/src/vendor.ts | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/public/docs/_examples/package.json b/public/docs/_examples/package.json
index 4f4dd51f00..672209a37d 100644
--- a/public/docs/_examples/package.json
+++ b/public/docs/_examples/package.json
@@ -32,7 +32,7 @@
"@angular/http": "2.0.0-rc.3",
"@angular/platform-browser": "2.0.0-rc.3",
"@angular/platform-browser-dynamic": "2.0.0-rc.3",
- "@angular/router": "3.0.0-alpha.7",
+ "@angular/router": "3.0.0-alpha.8",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.3",
"angular2-in-memory-web-api": "0.0.12",
diff --git a/public/docs/_examples/quickstart/js/package.1.json b/public/docs/_examples/quickstart/js/package.1.json
index b5b25a4f10..7f58576e80 100644
--- a/public/docs/_examples/quickstart/js/package.1.json
+++ b/public/docs/_examples/quickstart/js/package.1.json
@@ -14,7 +14,7 @@
"@angular/http": "2.0.0-rc.3",
"@angular/platform-browser": "2.0.0-rc.3",
"@angular/platform-browser-dynamic": "2.0.0-rc.3",
- "@angular/router": "3.0.0-alpha.7",
+ "@angular/router": "3.0.0-alpha.8",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.3",
diff --git a/public/docs/_examples/quickstart/ts/package.1.json b/public/docs/_examples/quickstart/ts/package.1.json
index 9353dfaa3e..e57d118d8f 100644
--- a/public/docs/_examples/quickstart/ts/package.1.json
+++ b/public/docs/_examples/quickstart/ts/package.1.json
@@ -18,7 +18,7 @@
"@angular/http": "2.0.0-rc.3",
"@angular/platform-browser": "2.0.0-rc.3",
"@angular/platform-browser-dynamic": "2.0.0-rc.3",
- "@angular/router": "3.0.0-alpha.7",
+ "@angular/router": "3.0.0-alpha.8",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.3",
diff --git a/public/docs/_examples/webpack/ts/package.webpack.json b/public/docs/_examples/webpack/ts/package.webpack.json
index 4064a86611..cc5948be7f 100644
--- a/public/docs/_examples/webpack/ts/package.webpack.json
+++ b/public/docs/_examples/webpack/ts/package.webpack.json
@@ -17,7 +17,7 @@
"@angular/http": "2.0.0-rc.3",
"@angular/platform-browser": "2.0.0-rc.3",
"@angular/platform-browser-dynamic": "2.0.0-rc.3",
- "@angular/router-deprecated": "2.0.0-rc.2",
+ "@angular/router": "3.0.0-alpha.8",
"core-js": "^2.4.0",
"reflect-metadata": "0.1.2",
"rxjs": "5.0.0-beta.6",
diff --git a/public/docs/_examples/webpack/ts/src/vendor.ts b/public/docs/_examples/webpack/ts/src/vendor.ts
index 1a45c91d46..ede1e2717d 100644
--- a/public/docs/_examples/webpack/ts/src/vendor.ts
+++ b/public/docs/_examples/webpack/ts/src/vendor.ts
@@ -5,7 +5,7 @@ import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
-import '@angular/router-deprecated';
+import '@angular/router';
// RxJS
import 'rxjs';
From 1c5be21b326b113c07778f06fb7adf00ef8b23ab Mon Sep 17 00:00:00 2001
From: eltronix
Date: Mon, 27 Jun 2016 20:06:12 +0300
Subject: [PATCH 07/31] Fixed typo
---
public/docs/ts/latest/guide/animations.jade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/docs/ts/latest/guide/animations.jade b/public/docs/ts/latest/guide/animations.jade
index 4bf6fe2be6..3068a20990 100644
--- a/public/docs/ts/latest/guide/animations.jade
+++ b/public/docs/ts/latest/guide/animations.jade
@@ -57,7 +57,7 @@ figure
:marked
With these we can now define an *animation trigger* called `heroState` in the component
metadata. It has animated transitions between two states: `active` and `inactive`. When a
- hero is active, we display a the element in slightly larger size and lighter color.
+ hero is active, we display the element in a slightly larger size and lighter color.
+makeExample('animations/ts/app/hero-list-basic.component.ts', 'animationdef')(format=".")
From 26027105a78ff2c9a4e0a8732b8896782aad61a3 Mon Sep 17 00:00:00 2001
From: Kai Ruhnau
Date: Mon, 27 Jun 2016 12:57:32 +0200
Subject: [PATCH 08/31] docs(router): Fix the link to the APP_BASE_HREF page
---
public/docs/ts/latest/guide/router.jade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/docs/ts/latest/guide/router.jade b/public/docs/ts/latest/guide/router.jade
index a92d0386c0..817912f031 100644
--- a/public/docs/ts/latest/guide/router.jade
+++ b/public/docs/ts/latest/guide/router.jade
@@ -1612,7 +1612,7 @@ code-example(format=".", language="bash").
.l-sub-section
:marked
- Learn about the [APP_BASE_HREF](../api/router/APP_BASE_HREF-let.html)
+ Learn about the [APP_BASE_HREF](../api/common/index/APP_BASE_HREF-let.html)
in the API Guide.
:marked
### *HashLocationStrategy*
From 2eae445504e59c6ab6b216d22e96fac95703b9c6 Mon Sep 17 00:00:00 2001
From: Rick Beerendonk
Date: Thu, 23 Jun 2016 14:09:49 +0200
Subject: [PATCH 09/31] docs(template-syntax): correct hyperlink path to API
documentation
---
public/docs/ts/latest/guide/template-syntax.jade | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/public/docs/ts/latest/guide/template-syntax.jade b/public/docs/ts/latest/guide/template-syntax.jade
index 2164fa744d..3414c3cdc0 100644
--- a/public/docs/ts/latest/guide/template-syntax.jade
+++ b/public/docs/ts/latest/guide/template-syntax.jade
@@ -881,7 +881,7 @@ block style-property-name-dart-diff
The `ngModel` input property sets the element's value property and the `ngModelChange` output property
listens for changes to the element's value.
The details are specific to each kind of element and therefore the `NgModel` directive only works for elements,
- such as the input text box, that are supported by a [ControlValueAccessor](../api/common/ControlValueAccessor-interface.html).
+ such as the input text box, that are supported by a [ControlValueAccessor](../api/common/index/ControlValueAccessor-interface.html).
We can't apply `[(ngModel)]` to our custom components until we write a suitable *value accessor*,
a technique that is beyond the scope of this chapter.
@@ -1120,7 +1120,7 @@ block dart-no-truthy-falsey
+makeExample('template-syntax/ts/app/app.component.html', 'NgFor-3')(format=".")
.l-sub-section
:marked
- Learn about other special *index-like* values such as `last`, `even`, and `odd` in the [NgFor API reference](../api/common/NgFor-directive.html).
+ Learn about other special *index-like* values such as `last`, `even`, and `odd` in the [NgFor API reference](../api/common/index/NgFor-directive.html).
:marked
#### NgForTrackBy
From f3189546a6a44cd0be77758269ff9df2173c640f Mon Sep 17 00:00:00 2001
From: Brandon Roberts
Date: Sun, 19 Jun 2016 00:20:38 -0400
Subject: [PATCH 10/31] docs(toh-5): Upgraded tutorial to new router
---
public/docs/_examples/styles.css | 26 +-
.../_examples/toh-5/ts/app/app.component.1.ts | 3 +-
.../_examples/toh-5/ts/app/app.component.2.ts | 15 +-
.../_examples/toh-5/ts/app/app.component.3.ts | 33 ++
.../_examples/toh-5/ts/app/app.component.css | 2 +-
.../_examples/toh-5/ts/app/app.component.ts | 34 +-
.../_examples/toh-5/ts/app/app.routes.1.ts | 37 ++
.../_examples/toh-5/ts/app/app.routes.2.ts | 14 +
.../docs/_examples/toh-5/ts/app/app.routes.ts | 32 ++
.../toh-5/ts/app/dashboard.component.ts | 4 +-
.../toh-5/ts/app/hero-detail.component.ts | 27 +-
.../toh-5/ts/app/heroes.component.ts | 4 +-
public/docs/_examples/toh-5/ts/app/main.ts | 6 +-
public/docs/_examples/toh-5/ts/plnkr.json | 2 +-
public/docs/ts/latest/tutorial/toh-pt5.jade | 392 +++++++++---------
15 files changed, 364 insertions(+), 267 deletions(-)
create mode 100644 public/docs/_examples/toh-5/ts/app/app.component.3.ts
create mode 100644 public/docs/_examples/toh-5/ts/app/app.routes.1.ts
create mode 100644 public/docs/_examples/toh-5/ts/app/app.routes.2.ts
create mode 100644 public/docs/_examples/toh-5/ts/app/app.routes.ts
diff --git a/public/docs/_examples/styles.css b/public/docs/_examples/styles.css
index 054b417f6f..62ddfa5121 100644
--- a/public/docs/_examples/styles.css
+++ b/public/docs/_examples/styles.css
@@ -1,20 +1,20 @@
/* Master Styles */
h1 {
- color: #369;
- font-family: Arial, Helvetica, sans-serif;
+ color: #369;
+ font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
-h2, h3 {
+h2, h3 {
color: #444;
- font-family: Arial, Helvetica, sans-serif;
+ font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
}
-body {
- margin: 2em;
+body {
+ margin: 2em;
}
-body, input[text], button {
- color: #888;
- font-family: Cambria, Georgia;
+body, input[text], button {
+ color: #888;
+ font-family: Cambria, Georgia;
}
a {
cursor: pointer;
@@ -34,7 +34,7 @@ button:hover {
}
button:disabled {
background-color: #eee;
- color: #aaa;
+ color: #aaa;
cursor: auto;
}
@@ -54,7 +54,7 @@ nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
-nav a.router-link-active {
+nav a.active {
color: #039be5;
}
@@ -137,6 +137,6 @@ nav a.router-link-active {
}
/* everywhere else */
-* {
- font-family: Arial, Helvetica, sans-serif;
+* {
+ font-family: Arial, Helvetica, sans-serif;
}
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.1.ts b/public/docs/_examples/toh-5/ts/app/app.component.1.ts
index 07a2317293..2f0e3506dd 100644
--- a/public/docs/_examples/toh-5/ts/app/app.component.1.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.component.1.ts
@@ -8,7 +8,7 @@ import { HeroesComponent } from './heroes.component';
// #enddocregion
// For testing only
-import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
+import { ROUTER_DIRECTIVES } from '@angular/router';
// #docregion
@Component({
@@ -20,7 +20,6 @@ import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/route
directives: [HeroesComponent],
providers: [
// #enddocregion
- ROUTER_PROVIDERS,
// #docregion
HeroService
]
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.2.ts b/public/docs/_examples/toh-5/ts/app/app.component.2.ts
index 6b690a6c63..c2699f317b 100644
--- a/public/docs/_examples/toh-5/ts/app/app.component.2.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.component.2.ts
@@ -2,38 +2,27 @@
// #docregion
import { Component } from '@angular/core';
// #docregion import-router
-import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
+import { ROUTER_DIRECTIVES } from '@angular/router';
// #enddocregion import-router
import { HeroService } from './hero.service';
-import { HeroesComponent } from './heroes.component';
@Component({
selector: 'my-app',
// #docregion template
template: `
{{title}}
- Heroes
+ Heroes
`,
// #enddocregion template
// #docregion directives-and-providers
directives: [ROUTER_DIRECTIVES],
providers: [
- ROUTER_PROVIDERS,
HeroService
]
// #enddocregion directives-and-providers
})
-// #docregion route-config
-@RouteConfig([
- {
- path: '/heroes',
- name: 'Heroes',
- component: HeroesComponent
- }
-])
-// #enddocregion route-config
export class AppComponent {
title = 'Tour of Heroes';
}
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.3.ts b/public/docs/_examples/toh-5/ts/app/app.component.3.ts
new file mode 100644
index 0000000000..ff64e27ab1
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/app.component.3.ts
@@ -0,0 +1,33 @@
+// #docplaster
+// #docregion
+import { Component } from '@angular/core';
+import { ROUTER_DIRECTIVES } from '@angular/router';
+
+import { HeroService } from './hero.service';
+
+@Component({
+ selector: 'my-app',
+ // #docregion template
+ template: `
+ {{title}}
+
+ // #docregion router-link-active
+ Dashboard
+ Heroes
+ // #enddocregion router-link-active
+
+
+ `,
+ // #enddocregion template
+ // #docregion style-urls
+ styleUrls: ['app/app.component.css'],
+ // #enddocregion style-urls
+ directives: [ROUTER_DIRECTIVES],
+ providers: [
+ HeroService
+ ]
+})
+export class AppComponent {
+ title = 'Tour of Heroes';
+}
+// #enddocregion
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.css b/public/docs/_examples/toh-5/ts/app/app.component.css
index f4e8082ea1..071e665767 100644
--- a/public/docs/_examples/toh-5/ts/app/app.component.css
+++ b/public/docs/_examples/toh-5/ts/app/app.component.css
@@ -24,6 +24,6 @@ nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
-nav a.router-link-active {
+nav a.active {
color: #039be5;
}
diff --git a/public/docs/_examples/toh-5/ts/app/app.component.ts b/public/docs/_examples/toh-5/ts/app/app.component.ts
index 5589cd84e9..3f3e758dcf 100644
--- a/public/docs/_examples/toh-5/ts/app/app.component.ts
+++ b/public/docs/_examples/toh-5/ts/app/app.component.ts
@@ -1,13 +1,8 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
-import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
+import { ROUTER_DIRECTIVES } from '@angular/router';
-import { DashboardComponent } from './dashboard.component';
-import { HeroesComponent } from './heroes.component';
-// #docregion hero-detail-import
-import { HeroDetailComponent } from './hero-detail.component';
-// #enddocregion hero-detail-import
import { HeroService } from './hero.service';
@Component({
@@ -16,8 +11,8 @@ import { HeroService } from './hero.service';
template: `
{{title}}
- Dashboard
- Heroes
+ Dashboard
+ Heroes
`,
@@ -27,32 +22,9 @@ import { HeroService } from './hero.service';
// #enddocregion style-urls
directives: [ROUTER_DIRECTIVES],
providers: [
- ROUTER_PROVIDERS,
HeroService
]
})
-@RouteConfig([
- // #docregion dashboard-route
- {
- path: '/dashboard',
- name: 'Dashboard',
- component: DashboardComponent,
- useAsDefault: true
- },
- // #enddocregion dashboard-route
- // #docregion hero-detail-route
- {
- path: '/detail/:id',
- name: 'HeroDetail',
- component: HeroDetailComponent
- },
- // #enddocregion hero-detail-route
- {
- path: '/heroes',
- name: 'Heroes',
- component: HeroesComponent
- }
-])
export class AppComponent {
title = 'Tour of Heroes';
}
diff --git a/public/docs/_examples/toh-5/ts/app/app.routes.1.ts b/public/docs/_examples/toh-5/ts/app/app.routes.1.ts
new file mode 100644
index 0000000000..17f2df4e98
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/app.routes.1.ts
@@ -0,0 +1,37 @@
+// #docregion
+import { provideRouter, RouterConfig } from '@angular/router';
+import { DashboardComponent } from './dashboard.component';
+import { HeroesComponent } from './heroes.component';
+// #docregion hero-detail-import
+import { HeroDetailComponent } from './hero-detail.component';
+// #enddocregion hero-detail-import
+
+export const routes: RouterConfig = [
+ // #docregion redirect-route
+ {
+ path: '',
+ redirectTo: '/dashboard',
+ terminal: true
+ },
+ // #enddocregion redirect-route
+ // #docregion dashboard-route
+ {
+ path: 'dashboard',
+ component: DashboardComponent
+ },
+ // #enddocregion dashboard-route
+ // #docregion hero-detail-route
+ {
+ path: 'detail/:id',
+ component: HeroDetailComponent
+ },
+ // #enddocregion hero-detail-route
+ {
+ path: 'heroes',
+ component: HeroesComponent
+ }
+];
+
+export const APP_ROUTER_PROVIDERS = [
+ provideRouter(routes)
+];
diff --git a/public/docs/_examples/toh-5/ts/app/app.routes.2.ts b/public/docs/_examples/toh-5/ts/app/app.routes.2.ts
new file mode 100644
index 0000000000..45ddeb9230
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/app.routes.2.ts
@@ -0,0 +1,14 @@
+// #docregion
+import { provideRouter, RouterConfig } from '@angular/router';
+import { HeroesComponent } from './heroes.component';
+
+const routes: RouterConfig = [
+ {
+ path: '/heroes',
+ component: HeroesComponent
+ }
+];
+
+export const APP_ROUTER_PROVIDERS = [
+ provideRouter(routes)
+];
diff --git a/public/docs/_examples/toh-5/ts/app/app.routes.ts b/public/docs/_examples/toh-5/ts/app/app.routes.ts
new file mode 100644
index 0000000000..b4f1f1efa1
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/app.routes.ts
@@ -0,0 +1,32 @@
+// #docregion
+import { provideRouter, RouterConfig } from '@angular/router';
+
+import { DashboardComponent } from './dashboard.component';
+import { HeroesComponent } from './heroes.component';
+// #docregion hero-detail-import
+import { HeroDetailComponent } from './hero-detail.component';
+// #enddocregion hero-detail-import
+
+export const routes: RouterConfig = [
+ {
+ path: '',
+ redirectTo: '/dashboard',
+ terminal: true
+ },
+ {
+ path: 'dashboard',
+ component: DashboardComponent
+ },
+ {
+ path: 'detail/:id',
+ component: HeroDetailComponent
+ },
+ {
+ path: 'heroes',
+ component: HeroesComponent
+ }
+];
+
+export const APP_ROUTER_PROVIDERS = [
+ provideRouter(routes)
+];
diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts
index e58760caad..6dd4b1abc2 100644
--- a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts
+++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts
@@ -2,7 +2,7 @@
// #docregion
import { Component, OnInit } from '@angular/core';
// #docregion import-router
-import { Router } from '@angular/router-deprecated';
+import { Router } from '@angular/router';
// #enddocregion import-router
import { Hero } from './hero';
@@ -36,7 +36,7 @@ export class DashboardComponent implements OnInit {
// #docregion goto-detail
gotoDetail(hero: Hero) {
- let link = ['HeroDetail', { id: hero.id }];
+ let link = ['/detail', hero.id];
this.router.navigate(link);
}
// #enddocregion goto-detail
diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts
index 96eb8aa93f..61edccb90e 100644
--- a/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts
+++ b/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts
@@ -1,11 +1,11 @@
// #docplaster
// #docregion
// #docregion import-oninit, v2
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, OnDestroy } from '@angular/core';
// #enddocregion import-oninit
-// #docregion import-route-params
-import { RouteParams } from '@angular/router-deprecated';
-// #enddocregion import-route-params
+// #docregion import-activated-route
+import { ActivatedRoute } from '@angular/router';
+// #enddocregion import-activated-route
import { Hero } from './hero';
// #docregion import-hero-service
@@ -23,27 +23,36 @@ import { HeroService } from './hero.service';
})
// #enddocregion extract-template
// #docregion implement
-export class HeroDetailComponent implements OnInit {
+export class HeroDetailComponent implements OnInit, OnDestroy {
// #enddocregion implement
hero: Hero;
+ sub: any;
// #docregion ctor
constructor(
private heroService: HeroService,
- private routeParams: RouteParams) {
+ private route: ActivatedRoute) {
}
// #enddocregion ctor
// #docregion ng-oninit
ngOnInit() {
// #docregion get-id
- let id = +this.routeParams.get('id');
+ this.sub = this.route.params.subscribe(params => {
+ let id = +params['id'];
+ this.heroService.getHero(id)
+ .then(hero => this.hero = hero);
+ });
// #enddocregion get-id
- this.heroService.getHero(id)
- .then(hero => this.hero = hero);
}
// #enddocregion ng-oninit
+ // #docregion ng-ondestroy
+ ngOnDestroy() {
+ this.sub.unsubscribe();
+ }
+ // #enddocregion ng-ondestroy
+
// #docregion go-back
goBack() {
window.history.back();
diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.ts b/public/docs/_examples/toh-5/ts/app/heroes.component.ts
index cd43e03b86..c0dbd9c8e7 100644
--- a/public/docs/_examples/toh-5/ts/app/heroes.component.ts
+++ b/public/docs/_examples/toh-5/ts/app/heroes.component.ts
@@ -1,7 +1,7 @@
// #docplaster
// #docregion
import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router-deprecated';
+import { Router } from '@angular/router';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@@ -36,7 +36,7 @@ export class HeroesComponent implements OnInit {
onSelect(hero: Hero) { this.selectedHero = hero; }
gotoDetail() {
- this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
+ this.router.navigate(['/detail', this.selectedHero.id]);
}
// #docregion heroes-component-renaming
}
diff --git a/public/docs/_examples/toh-5/ts/app/main.ts b/public/docs/_examples/toh-5/ts/app/main.ts
index ad256f0823..da35003df1 100644
--- a/public/docs/_examples/toh-5/ts/app/main.ts
+++ b/public/docs/_examples/toh-5/ts/app/main.ts
@@ -1,5 +1,9 @@
+// #docregion
import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
+import { APP_ROUTER_PROVIDERS } from './app.routes';
-bootstrap(AppComponent);
+bootstrap(AppComponent, [
+ APP_ROUTER_PROVIDERS
+]);
diff --git a/public/docs/_examples/toh-5/ts/plnkr.json b/public/docs/_examples/toh-5/ts/plnkr.json
index 019630c28f..fbed287e3f 100644
--- a/public/docs/_examples/toh-5/ts/plnkr.json
+++ b/public/docs/_examples/toh-5/ts/plnkr.json
@@ -3,7 +3,7 @@
"files":[
"!**/*.d.ts",
"!**/*.js",
- "!**/*.[1,2].*"
+ "!**/*.[1,2,3].*"
],
"tags": ["tutorial", "tour", "heroes", "router"]
}
diff --git a/public/docs/ts/latest/tutorial/toh-pt5.jade b/public/docs/ts/latest/tutorial/toh-pt5.jade
index 9500cc490f..160672fb9a 100644
--- a/public/docs/ts/latest/tutorial/toh-pt5.jade
+++ b/public/docs/ts/latest/tutorial/toh-pt5.jade
@@ -2,12 +2,12 @@ include ../_util-fns
:marked
# 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.
* Navigate between the *Heroes* and *Dashboard* views.
* 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:
figure.image-display
img(src='/resources/images/devguide/toh/nav-diagram.png' alt="View navigations")
@@ -15,21 +15,21 @@ figure.image-display
We'll add Angular’s *Component Router* to our app to satisfy these requirements.
.l-sub-section
:marked
- The [Routing and Navigation](../guide/router-deprecated.html) chapter covers the router in more detail
- than we will in this tutorial.
+ The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
+ than we will in this tutorial.
p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
.l-sub-section
img(src='/resources/images/devguide/plunker-separate-window-button.png' alt="pop out the window" align="right" style="margin-right:-20px")
:marked
- To see the URL changes in the browser address bar,
+ To see the URL changes in the browser address bar,
pop out the preview window by clicking the blue 'X' button in the upper right corner:
.l-main-section
:marked
## Where We Left Off
- Before we continue with our Tour of Heroes, let’s verify that we have the following structure after adding our hero service
+ Before we continue with our Tour of Heroes, let’s verify that we have the following structure after adding our hero service
and hero detail component. If not, we’ll need to go back and follow the previous chapters.
.filetree
@@ -44,7 +44,7 @@ p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
.file main.ts
.file mock-heroes.ts
.file node_modules ...
- .file typings ...
+ .file typings ...
.file index.html
.file package.json
.file styles.css
@@ -64,7 +64,7 @@ code-example(language="bash").
## Action plan
Here's our plan:
-
+
* Turn `AppComponent` into an application shell that only handles navigation
* Relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`
* Add routing
@@ -74,13 +74,13 @@ code-example(language="bash").
.l-sub-section
:marked
*Routing* is another name for *navigation*. The *router* is the mechanism for navigating from view to view.
-
-.l-main-section
+
+.l-main-section
:marked
## Splitting the *AppComponent*
-
+
Our current app loads `AppComponent` and immediately displays the list of heroes.
-
+
Our revised app should present a shell with a choice of views (*Dashboard* and *Heroes*) and then default to one of them.
The `AppComponent` should only handle navigation.
@@ -101,11 +101,11 @@ code-example(language="bash").
:marked
## Create *AppComponent*
- The new `AppComponent` will be the application shell.
+ The new `AppComponent` will be the application shell.
It will have some navigation links at the top and a display area below for the pages we navigate to.
-
+
The initial steps are:
-
+
* create a new file named `app.component.ts`.
* define an `AppComponent` class.
* `export` it so we can reference it during bootstrapping in `main.ts`.
@@ -116,7 +116,7 @@ code-example(language="bash").
* add the `HeroesComponent` to the `directives` array so Angular recognizes the `` tags.
* add the `HeroService` to the `providers` array because we'll need it in every other view.
* add the supporting `import` statements.
-
+
Our first draft looks like this:
+makeExample('toh-5/ts/app/app.component.1.ts', null, 'app/app.component.ts (v1)')
:marked
@@ -127,104 +127,99 @@ code-example(language="bash").
We are *promoting* this service from the `HeroesComponent` to the `AppComponent`.
We ***do not want two copies*** of this service at two different levels of our app.
:marked
- The app still runs and still displays heroes.
+ The app still runs and still displays heroes.
Our refactoring of `AppComponent` into a new `AppComponent` and a `HeroesComponent` worked!
We have done no harm.
:marked
## Add Routing
-
- We're ready to take the next step.
+
+ We're ready to take the next step.
Instead of displaying heroes automatically, we'd like to show them *after* the user clicks a button.
In other words, we'd like to navigate to the list of heroes.
-
+
We'll need the Angular *Component Router*.
-
+
### Set the base tag
- Open the `index.html` and add ` ` at the top of the `` section.
+ Open the `index.html` and add ` ` at the top of the `` section.
+makeExample('toh-5/ts/index.html', 'base-href', 'index.html (base href)')(format=".")
.callout.is-important
header base href is essential
:marked
- See the *base href* section of the [Router](../guide/router-deprecated.html#!#base-href) chapter to learn why this matters.
+ See the *base href* section of the [Router](../guide/router.html#!#base-href) chapter to learn why this matters.
:marked
- ### Make the router available.
- The *Component Router* is a service. Like any service, we have to import it and make it
- available to the application by adding it to the `providers` array.
-
- The Angular router is a combination of multiple services (`ROUTER_PROVIDERS`), multiple directives (`ROUTER_DIRECTIVES`),
- and a configuration decorator (`RouteConfig`). We'll import them all together:
-+makeExample('toh-5/ts/app/app.component.2.ts', 'import-router', 'app/app.component.ts (router imports)')(format=".")
-:marked
- Next we update the `directives` and `providers` metadata arrays to *include* the router assets.
-+makeExample('toh-5/ts/app/app.component.2.ts', 'directives-and-providers', 'app/app.component.ts (directives and providers)')(format=".")
-:marked
- Notice that we also removed the `HeroesComponent` from the `directives` array.
- `AppComponent` no longer shows heroes; that will be the router's job.
- We'll soon remove `` from the template too.
-
- ### Add and configure the router
-
- The `AppComponent` doesn't have a router yet. We'll use the `@RouteConfig` decorator to simultaneously
- (a) assign a router to the component and (b) configure that router with *routes*.
-
- *Routes* tell the router which views to display when a user clicks a link or
+ The Angular router is a combination of multiple provided services (`provideRouter`), multiple directives (`ROUTER_DIRECTIVES`),
+ and a configuration (`RouterConfig`). We'll configure our routes first:
+
+ ### Configure and add the router
+
+ Our application doesn't have a router yet. We'll create a configuration file for our routes that
+ does two things
+ (a) configure that router with *routes*. (b) provide an export to add the router to our bootstrap
+
+ *Routes* tell the router which views to display when a user clicks a link or
pastes a URL into the browser address bar.
Let's define our first route, a route to the `HeroesComponent`.
-+makeExample('toh-5/ts/app/app.component.2.ts', 'route-config', 'app/app.component.ts (RouteConfig for heroes)')(format=".")
++makeExample('toh-5/ts/app/app.routes.2.ts', '', 'app/app.routes.ts')(format=".")
:marked
- `@RouteConfig` takes an array of *route definitions*.
- We have only one route definition at the moment but rest assured, we'll add more.
-
- This *route definition* has three parts:
+ The `RouterConfig` is an array of *route definitions*.
+ We have only one route definition at the moment but rest assured, we'll add more.
+
+ This *route definition* has two parts:
* **path**: the router matches this route's path to the URL in the browser address bar (`/heroes`).
-
- * **name**: the official name of the route; it *must* begin with a capital letter to avoid confusion with the *path* (`Heroes`).
-
+
* **component**: the component that the router should create when navigating to this route (`HeroesComponent`).
.l-sub-section
:marked
- Learn more about defining routes with @RouteConfig in the [Routing](../guide/router-deprecated.html) chapter.
+ Learn more about defining routes with RouterConfig in the [Routing](../guide/router.html) chapter.
+
+:marked
+ ### Make the router available.
+ The *Component Router* is a service. We have to import our `APP_ROUTER_PROVIDERS` which
+ contains our configured router and make it available to the application by adding it to
+ the `bootstrap` array.
++makeExample('toh-5/ts/app/main.ts', '', 'app/main.ts')(format=".")
+
:marked
### Router Outlet
- If we paste the path, `/heroes`, into the browser address bar,
+ If we paste the path, `/heroes`, into the browser address bar,
the router should match it to the `'Heroes'` route and display the `HeroesComponent`.
But where?
-
+
We have to ***tell it where*** by adding `` marker tags to the bottom of the template.
`RouterOutlet` is one of the `ROUTER_DIRECTIVES`.
The router displays each component immediately below the `` as we navigate through the application.
-
+
### Router Links
We don't really expect users to paste a route URL into the address bar.
We add an anchor tag to the template which, when clicked, triggers navigation to the `HeroesComponent`.
-
+
The revised template looks like this:
+makeExample('toh-5/ts/app/app.component.2.ts', 'template', 'app/app.component.ts (template v1)')(format=".")
: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 an array
that tells the router where to navigate when the user clicks the link.
-
+
We define a *routing instruction* with a *link parameters array*.
- The array only has one element in our little sample, the quoted ***name* of the route** to follow.
- Looking back at the route configuration, we confirm that `'Heroes'` is the name of the route to the `HeroesComponent`.
+ The array only has one element in our little sample, the quoted ***path* of the route** to follow.
+ Looking back at the route configuration, we confirm that `'/heroes'` is the path of the route to the `HeroesComponent`.
.l-sub-section
:marked
- Learn about the *link parameters array* in the [Routing](../guide/router-deprecated.html#link-parameters-array) chapter.
+ Learn about the *link parameters array* in the [Routing](../guide/router.html#link-parameters-array) chapter.
:marked
- Refresh the browser. We see only the app title. We don't see the heroes list.
+ Refresh the browser. We see only the app title. We don't see the heroes list.
.l-sub-section
:marked
- The browser's address bar shows `/`.
- The route path to `HeroesComponent` is `/heroes`, not `/`.
+ The browser's address bar shows `/`.
+ The route path to `HeroesComponent` is `/heroes`, not `/`.
We don't have a route that matches the path `/`, so there is nothing to show.
That's something we'll want to fix.
:marked
- We click the "Heroes" navigation link, the browser bar updates to `/heroes`,
+ We click the "Heroes" navigation link, the browser bar updates to `/heroes`,
and now we see the list of heroes. We are navigating at last!
At this stage, our `AppComponent` looks like this.
@@ -238,73 +233,77 @@ code-example(language="bash").
:marked
## Add a *Dashboard*
Routing only makes sense when we have multiple views. We need another view.
-
+
Create a placeholder `DashboardComponent` that gives us something to navigate to and from.
+makeExample('toh-5/ts/app/dashboard.component.1.ts',null, 'app/dashboard.component.ts (v1)')(format=".")
:marked
We’ll come back and make it more useful later.
### Configure the dashboard route
- Go back to `app.component.ts` and teach it to navigate to the dashboard.
-
- Import the `DashboardComponent` so we can reference it in the dashboard route definition.
-
- Add the following `'Dashboard'` route definition to the `@RouteConfig` array of definitions.
-+makeExample('toh-5/ts/app/app.component.ts','dashboard-route', 'app/app.component.ts (Dashboard route)')(format=".")
+ Go back to `app.routes.ts` and teach it to navigate to the dashboard.
+
+ Import the `DashboardComponent` so we can reference it in the dashboard route definition.
+
+ Add the following `'Dashboard'` route definition to the `RouterConfig` array of definitions.
++makeExample('toh-5/ts/app/app.routes.1.ts','dashboard-route', 'app/app.routes.ts (Dashboard route)')(format=".")
.l-sub-section
:marked
- **useAsDefault**
-
- We want the app to show the dashboard when it starts and
+ **Redirect**
+
+ We want the app to show the dashboard when it starts and
we want to see a nice URL in the browser address bar that says `/dashboard`.
- Remember that the browser launches with `/` in the address bar.
- We don't have a route for that path and we'd rather not create one.
-
- Fortunately we can add the `useAsDefault: true` property to the *route definition* and the
- router will display the dashboard when the browser URL doesn't match an existing route.
+ Remember that the browser launches with `/` in the address bar.
+ We can use a redirect route to make this happen.
+
++makeExample('toh-5/ts/app/app.routes.1.ts','redirect-route', 'app/app.routes.ts (Redirect route)')(format=".")
+
+.l-sub-section
+ :marked
+ Learn about the *redirects* in the [Routing](../guide/router.html#!#redirect) chapter.
+
:marked
Finally, add a dashboard navigation link to the template, just above the *Heroes* link.
+makeExample('toh-5/ts/app/app.component.ts','template', 'app/app.component.ts (template)')(format=".")
.l-sub-section
:marked
- We nestled the two links within `` tags.
+ We nestled the two links within `` tags.
They don't do anything yet but they'll be convenient when we style the links a little later in the chapter.
:marked
- Refresh the browser. The app displays the dashboard and
+ Refresh the browser. The app displays the dashboard and
we can navigate between the dashboard and the heroes.
## Dashboard Top Heroes
Let’s spice up the dashboard by displaying the top four heroes at a glance.
-
+
Replace the `template` metadata with a `templateUrl` property that points to a new
template file.
-
+
+makeExample('toh-5/ts/app/dashboard.component.ts', 'template-url', 'app/dashboard.component.ts (templateUrl)')(format=".")
.l-sub-section
:marked
- We specify the path _all the way back to the application root_ — `app/` in this case —
+ We specify the path _all the way back to the application root_ — `app/` in this case —
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
Create that file with these contents:
+makeExample('toh-5/ts/app/dashboard.component.html', null, 'app/dashboard.component.html')(format=".")
: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 `` elements to help with styling later in this chapter.
-
- There's a `(click)` binding to a `gotoDetail` method we haven't written yet and
+
+ 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*
-
+
We'd like to re-use the `HeroService` to populate the component's `heroes` array.
-
+
Recall earlier in the chapter that we removed the `HeroService` from the `providers` array of the `HeroesComponent`
and added it to the `providers` array 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.
Angular will inject `HeroService` and we'll use it here in the `DashboardComponent`.
### Get heroes
@@ -321,13 +320,13 @@ code-example(language="bash").
* create a `heroes` array property
* inject the `HeroService` in the constructor and hold it in a private `heroService` field.
* 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) with *slice*
and stub the `gotoDetail` method until we're ready to implement it.
-
+
Refresh the browser and see four heroes in the new dashboard.
-.l-main-section
+.l-main-section
:marked
## Navigate to Hero Details
@@ -336,23 +335,23 @@ code-example(language="bash").
1. from the *Dashboard* to a selected hero.
1. from the *Heroes* list to a selected hero.
1. from a "deep link" URL pasted into the browser address bar.
-
+
Adding a `'HeroDetail'` route seem an obvious place to start.
-
+
### Routing to a hero detail
-
+
We'll add a route to the `HeroDetailComponent` in the `AppComponent` where our other routes are configured.
-
- The new route is a bit unusual in that we must tell the `HeroDetailComponent` *which hero to show*.
+
+ The new route is a bit unusual in that we must tell the `HeroDetailComponent` *which hero to show*.
We didn't have to tell the `HeroesComponent` or the `DashboardComponent` anything.
-
+
At the moment the parent `HeroesComponent` sets the component's `hero` property to a hero object with a binding like this.
code-example(format='').
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
:marked
- That clearly won't work in any of our routing scenarios.
+ That clearly won't work in any of our routing scenarios.
Certainly not the last one; we can't embed an entire hero object in the URL! Nor would we want to.
-
+
### Parameterized route
We *can* add the hero's `id` to the URL. When routing to the hero whose `id` is 11, we could expect to see an URL such as this:
code-example(format='').
@@ -360,93 +359,99 @@ code-example(format='').
:marked
The `/detail/` part of that URL is constant. The trailing numeric `id` part changes from hero to hero.
We need to represent that variable part of the route with a *parameter* (or *token*) that stands for the hero's `id`.
-
+
### Configure a Route with a Parameter
-
+
Here's the *route definition* we'll use.
-+makeExample('toh-5/ts/app/app.component.ts','hero-detail-route', 'app/app.component.ts (route to HeroDetailComponent)')(format=".")
++makeExample('toh-5/ts/app/app.routes.1.ts','hero-detail-route', 'app/app.routes.ts (route to HeroDetailComponent)')(format=".")
: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`.
.l-sub-section
:marked
Of course we have to import the `HeroDetailComponent` before we create this route:
- +makeExample('toh-5/ts/app/app.component.ts','hero-detail-import')(format=".")
+ +makeExample('toh-5/ts/app/app.routes.1.ts','hero-detail-import')(format=".")
:marked
- We're finished with the `AppComponent`.
-
+ We're finished with the application routes.
+
We won't add a `'Hero Detail'` link to the template because users
don't click a navigation *link* to view a particular hero.
They click a *hero* whether that hero is displayed on the dashboard or in the heroes list.
-
+
We'll get to those *hero* clicks later in the chapter.
There's no point in working on them until the `HeroDetailComponent`
is ready to be navigated *to*.
-
+
That will require an `HeroDetailComponent` overhaul.
-.l-main-section
+.l-main-section
:marked
## Revise the *HeroDetailComponent*
-
+
Before we rewrite the `HeroDetailComponent`, let's review what it looks like now:
+makeExample('toh-4/ts/app/hero-detail.component.ts', null, 'app/hero-detail.component.ts (current)')
:marked
The template won't change. We'll display a hero the same way. The big changes are driven by how we get the hero.
-
- 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
- and use the `HeroService` to fetch the hero with that `id`.
- We need an import statement to reference the `RouteParams`.
-+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-route-params')(format=".")
+ We will no longer receive the hero in a parent component property binding.
+ The new `HeroDetailComponent` should take the `id` parameter from the `params` observable
+ in the `ActivatedRoute` service and use the `HeroService` to fetch the hero with that `id`.
+
+ We need an import statement to reference the `ActivatedRoute`.
++makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-activated-route')(format=".")
:marked
We import the `HeroService`so we can fetch a hero.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-hero-service')(format=".")
:marked
- We import the `OnInit` interface because we'll call the `HeroService` inside the `ngOnInit` component lifecycle hook.
+ We import the `OnInit` and `OnDestroy` interfaces because we'll call the `HeroService` inside the `ngOnInit` component lifecycle hook
+ and we'll clean up our `params` subscription in the `ngOnDestroy`.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-oninit')(format=".")
:marked
- We inject the both the `RouteParams` service and the `HeroService` into the constructor as we've done before,
+ We inject the both the `ActivatedRoute` service and the `HeroService` into the constructor as we've done before,
making private variables for both:
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'ctor', 'app/hero-detail.component.ts (constructor)')(format=".")
:marked
- We tell the class that we want to implement the `OnInit` interface.
+ We tell the class that we want to implement the `OnInit` and `OnDestroy` interfaces.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'implement')(format=".")
:marked
- Inside the `ngOnInit` lifecycle hook, extract the `id` parameter value from the `RouteParams` service
+ Inside the `ngOnInit` lifecycle hook, we _subscribe_ to the `params` observable to
+ extract the `id` parameter value from the `ActivateRoute` service
and use the `HeroService` to fetch the hero with that `id`.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'ng-oninit', 'app/hero-detail.component.ts (ngOnInit)')(format=".")
:marked
- Notice how we extract the `id` by calling the `RouteParams.get` method.
+ Inside the `ngOnDestroy` lifecycle hook, we _unsubscribe_ from the `params` subscription.
++makeExample('toh-5/ts/app/hero-detail.component.ts', 'ng-ondestroy', 'app/hero-detail.component.ts (ngOnDestroy)')(format=".")
+:marked
+ Notice how we extract the `id` by calling the `subscribe` method
+ which will deliver our array of route parameters.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'get-id')(format=".")
:marked
The hero `id` is a number. Route parameters are *always strings*.
- So we convert the route parameter value to a number with the JavaScript (+) operator.
-
+ So we convert the route parameter value to a number with the JavaScript (+) operator.
+
### Add *HeroService.getHero*
The problem with this bit of code is that `HeroService` doesn't have a `getHero` method!
We better fix that quickly before someone notices that we broke the app.
-
+
Open `HeroService` and add a `getHero` method that filters the heroes list from `getHeroes` by `id`:
+makeExample('toh-5/ts/app/hero.service.ts', 'get-hero', 'app/hero.service.ts (getHero)')(format=".")
:marked
Return to the `HeroDetailComponent` to clean up loose ends.
-
+
### Find our way back
-
- We can navigate *to* the `HeroDetailComponent` in several ways.
+
+ We can navigate *to* the `HeroDetailComponent` in several ways.
How do we navigate somewhere else when we're done?
-
+
The user could click one of the two links in the `AppComponent`. Or click the browser's back button.
- We'll add a third option, a `goBack` method that navigates backward one step in the browser's history stack
-
+ We'll add a third option, a `goBack` method that navigates backward one step in the browser's history stack
+
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'go-back', 'app/hero-detail.component.ts (goBack)')(format=".")
.l-sub-section
:marked
- Going back too far could take us out of the application.
+ Going back too far could take us out of the application.
That's acceptable in a demo. We'd guard against it in a real application,
- perhaps with the [*routerCanDeactivate* hook](../api/router/CanDeactivate-interface.html).
+ perhaps with the [*CanDeactivate* guard](../api/router/index/CanDeactivate-interface.html).
:marked
Then we wire this method with an event binding to a *Back* button that we add to the bottom of the component template.
+makeExample('toh-5/ts/app/hero-detail.component.html', 'back-button')(format=".")
@@ -465,28 +470,28 @@ code-example(format='').
:marked
## 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.
-
+
In the dashboard template we bound each hero's click event to the `gotoDetail` method, passing along the selected `hero` entity.
+makeExample('toh-5/ts/app/dashboard.component.html','click', 'app/dashboard.component.html (click binding)')(format=".")
:marked
- We stubbed the `gotoDetail` method when we rewrote the `DashboardComponent`.
- Now we give it a real implementation.
+ We stubbed the `gotoDetail` method when we rewrote the `DashboardComponent`.
+ Now we give it a real implementation.
+makeExample('toh-5/ts/app/dashboard.component.ts','goto-detail', 'app/dashboard.component.ts (gotoDetail)')(format=".")
:marked
The `gotoDetail` method navigates in two steps:
1. set a route *link parameters array*
1. pass the array to the router's navigate method.
-
+
We wrote *link parameters arrays* in the `AppComponent` for the navigation links.
- Those arrays had only one element, the name of the destination route.
-
- This array has two elements, the ***name*** of the destination route and a ***route parameter object***
+ Those arrays had only one element, the path of the destination route.
+
+ This array has two elements, the ***path*** of the destination route and a ***route parameter***
with an `id` field set to the value of the selected hero's `id`.
-
- The two array items align with the ***name*** and ***:id*** token in the parameterized `HeroDetail` route configuration we added to `AppComponent` earlier in the chapter.
-+makeExample('toh-5/ts/app/app.component.ts','hero-detail-route', 'app/app.component.ts (hero detail route)')(format=".")
+
+ The two array items align with the ***path*** and ***:id*** token in the parameterized `HeroDetail` route configuration we added to `app.routes.ts` earlier in the chapter.
++makeExample('toh-5/ts/app/app.routes.1.ts','hero-detail-route', 'app/app.routes.ts (hero detail route)')(format=".")
: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`):
+makeExample('toh-5/ts/app/dashboard.component.ts','import-router', 'app/dashboard.component.ts (excerpts)')(format=".")
@@ -498,31 +503,31 @@ code-example(format='').
:marked
## Select a Hero in the *HeroesComponent*
We'll do something similar in the `HeroesComponent`.
-
+
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.
+makeExample('toh-4/ts/app/app.component.ts','template', 'app/heroes.component.ts (current template)')(format=".")
:marked
Delete the last line of the template with the `
` 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.
-
- But we'll throw in a small twist for variety.
+
+ But we'll throw in a small twist for variety.
When the user selects a hero from the list, we *won't* go to the detail page.
We'll show a *mini-detail* on *this* page instead and make the user click a button to navigate to the *full detail *page.
-
+
### Add the *mini-detail*
Add the following HTML fragment at the bottom of the template where the `` used to be:
+makeExample('toh-5/ts/app/heroes.component.html','mini-detail')(format=".")
:marked
After clicking a hero, the user should see something like this below the hero list:
-
+
figure.image-display
img(src='/resources/images/devguide/toh/mini-hero-detail.png' alt="Mini Hero Detail" height="70")
:marked
### Format with 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 ( | ).
+makeExample('toh-5/ts/app/heroes.component.html','pipe')(format=".")
@@ -536,17 +541,17 @@ figure.image-display
### Move content out of the component file
We are not done. We still have to update the component class to support navigation to the
`HeroDetailComponent` when the user clicks the *View Details* button.
-
- This component file is really big. Most of it is either template or CSS styles.
+
+ This component file is really big. Most of it is either template or CSS styles.
It's difficult to find the component logic amidst the noise of HTML and CSS.
-
+
Let's migrate the template and the styles to their own files before we make any more changes:
1. *Cut-and-paste* the template contents into a new `heroes.component.html` 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.
-
- Because the template for `HeroesComponent` no longer uses `HeroDetailComponent`
- directly — instead using the router to _navigate_ to it — we can
+
+ 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` property. The revised
`@Component` looks like this:
@@ -556,17 +561,17 @@ figure.image-display
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. 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 array*.
-
+
Here's the revised component class:
+makeExample('toh-5/ts/app/heroes.component.ts', 'class', 'app/heroes.component.ts (class)')
:marked
- Refresh the browser and start clicking.
+ Refresh the browser and start clicking.
We can navigate around the app, from the dashboard to hero details and back,
- for heroes list to the mini-detail to the hero details and back to the heroes again.
+ for heroes list to the mini-detail to the hero details and back to the heroes again.
We can jump back and forth between the dashboard and the heroes.
-
+
We've met all of the navigational requirements that propelled this chapter.
.l-main-section
@@ -576,14 +581,14 @@ figure.image-display
Our creative designer team provided some CSS files to make it look better.
### A Dashboard with Style
- The designers think we should display the dashboard heroes in a row of rectangles.
+ The designers think we should display the dashboard heroes in a row of rectangles.
They've given us ~60 lines of CSS for this purpose including some simple media queries for responsive design.
If we paste these ~60 lines into the component `styles` metadata,
- they'll completely obscure the component logic.
- Let's not do that. It's easier to edit CSS in a separate `*.css` file anyway.
+ they'll completely obscure the component logic.
+ Let's not do that. It's easier to edit CSS in a separate `*.css` file anyway.
- Add a `dashboard.component.css` file to the `app` folder and reference
+ Add a `dashboard.component.css` file to the `app` folder and reference
that file in the component metadata's `styleUrls` array property like this:
+makeExample('toh-5/ts/app/dashboard.component.ts', 'css', 'app/dashboard.component.ts (styleUrls)')(format=".")
:marked
@@ -595,11 +600,11 @@ figure.image-display
:marked
### Stylish Hero Details
The designers also gave us CSS styles specifically for the `HeroDetailComponent`.
-
- Add a `hero-detail.component.css` to the `app` folder and refer to that file inside
+
+ Add a `hero-detail.component.css` to the `app` folder and refer to that file inside
the `styleUrls` array as we did for `DashboardComponent`.
-
- Here's the content for the aforementioned component CSS files.
+
+ Here's the content for the aforementioned component CSS files.
+makeTabs(
`toh-5/ts/app/hero-detail.component.css,
toh-5/ts/app/dashboard.component.css`,
@@ -610,29 +615,31 @@ figure.image-display
### Style the Navigation Links
The designers gave us CSS to make the navigation links in our `AppComponent` look more like selectable buttons.
We cooperated by surrounding those links in `` tags.
-
+
Add a `app.component.css` file to the `app` folder with the following content.
+makeExample('toh-5/ts/app/app.component.css', '', 'app/app.component.css (navigation styles)')
.l-sub-section
:marked
- **The *router-link-active* class**
-
- The Angular Router adds the `router-link-active` class to the HTML navigation element
- whose route matches the active route. All we have to do is define the style for it. Sweet!
+ **The *routerLinkActive* directive**
+
+ The Angular Router provides a `routerLinkActive` directive we can use to
+ to add a class to the HTML navigation element whose route matches the active route.
+ All we have to do is define the style for it. Sweet!
++makeExample('toh-5/ts/app/app.component.3.ts', 'router-link-active', 'app/app.component.ts (active router links)')(format=".")
:marked
- Set the `AppComponent`’s `styleUrls` property to this CSS file.
+ Set the `AppComponent`’s `styleUrls` property to this CSS file.
+makeExample('toh-5/ts/app/app.component.ts','style-urls', 'app/app.component.ts (styleUrls)')(format=".")
:marked
### Global application styles
- When we add styles to a component, we're keeping everything a component needs
+ When we add styles to a component, we're keeping everything a component needs
— HTML, the CSS, the code — together in one convenient place.
It's pretty easy to package it all up and re-use the component somewhere else.
-
+
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.
- These correspond to the full set of master styles that we
- introduced earlier (see
+ These correspond to the full set of master styles that we
+ introduced earlier (see
[QuickStart, "Add some style"](../quickstart.html#!#add-some-style)).
Here is an excerpt.
@@ -648,7 +655,7 @@ figure.image-display
+makeExample('toh-5/ts/index.html','css', 'index.html (link ref)')(format=".")
:marked
Look at the app now. Our dashboard, heroes, and navigation links are styling!
-
+
figure.image-display
img(src='/resources/images/devguide/toh/dashboard-top-heroes.png' alt="View navigations")
@@ -667,6 +674,7 @@ p.
.children
.file app.component.ts
.file app.component.css
+ .file app.routes.ts
.file dashboard.component.css
.file dashboard.component.html
.file dashboard.component.ts
@@ -681,7 +689,7 @@ p.
.file main.ts
.file mock-heroes.ts
.file node_modules ...
- .file typings ...
+ .file typings ...
.file index.html
.file package.json
.file styles.css
@@ -704,7 +712,7 @@ p.
### The Road Ahead
We have much of the foundation we need to build an application.
- We're still missing a key piece: remote data access.
-
- In the next chapter,
+ We're still missing a key piece: remote data access.
+
+ In the next chapter,
we’ll replace our mock data with data retrieved from a server using http.
From adc04b683018de9ca852a900ddbf1ffdb931ad8f Mon Sep 17 00:00:00 2001
From: Patrick McDonald
Date: Wed, 22 Jun 2016 13:48:00 -0400
Subject: [PATCH 11/31] docs: Change LoggerService to Logger service
`LoggerService` implies that it will be written as such in the code, yet the hero.service.ts example has a service simply called `Logger` (which matches the Style Guide).
---
public/docs/ts/latest/guide/architecture.jade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/docs/ts/latest/guide/architecture.jade b/public/docs/ts/latest/guide/architecture.jade
index e7ee02863b..a341a79b26 100644
--- a/public/docs/ts/latest/guide/architecture.jade
+++ b/public/docs/ts/latest/guide/architecture.jade
@@ -402,7 +402,7 @@ figure
+makeExample('architecture/ts/app/logger.service.ts', 'class', 'app/logger.service.ts (class only)')(format=".")
:marked
Here's a `HeroService` that fetches heroes and returns them in a resolved [promise](http://exploringjs.com/es6/ch_promises.html).
- The `HeroService` depends on the `LoggerService` and another `BackendService` that handles the server communication grunt work.
+ The `HeroService` depends on the `Logger` service and another `BackendService` that handles the server communication grunt work.
+makeExample('architecture/ts/app/hero.service.ts', 'class', 'app/hero.service.ts (class only)')(format=".")
:marked
Services are everywhere.
From c467d56a2b435afa7105ddcac0606d3e7bdfbbd8 Mon Sep 17 00:00:00 2001
From: Mark McEahern
Date: Tue, 21 Jun 2016 10:55:52 -0500
Subject: [PATCH 12/31] Fix typo in first-app-tests.jade
---
public/docs/ts/latest/testing/first-app-tests.jade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/docs/ts/latest/testing/first-app-tests.jade b/public/docs/ts/latest/testing/first-app-tests.jade
index 3df9bf04bb..9824bf2b17 100644
--- a/public/docs/ts/latest/testing/first-app-tests.jade
+++ b/public/docs/ts/latest/testing/first-app-tests.jade
@@ -185,7 +185,7 @@ figure.image-display
Once configured with a default extension of 'js', SystemJS requests `hero.js` which *does* exist and is promptly returned by our server.
### Asynchronous System.import
- The call to `System.import` shouldn't surprise us but it's asynchronous nature might.
+ The call to `System.import` shouldn't surprise us but its asynchronous nature might.
If we ponder this for a moment, we realize that it must be asynchronous because
System.js may have to fetch the corresponding JavaScript file from the server.
Accordingly, `System.import` returns a promise and we must wait for that promise to resolve.
From 58d20e57b536601b237b9e1f0dc5af9f2a81697d Mon Sep 17 00:00:00 2001
From: Filipe Silva
Date: Tue, 21 Jun 2016 03:03:31 +0100
Subject: [PATCH 13/31] chore: update ngSwitchWhen to ngSwitchCase
See https://github.com/angular/angular/commit/e1fcab7
---
.../ts/app/movie-list.component.html | 4 ++--
.../ts/app/dynamic-form-question.component.html | 4 ++--
.../ts/app/structural-directives.component.html | 4 ++--
.../template-syntax/ts/app/app.component.html | 16 ++++++++--------
.../latest/cookbook/a1-a2-quick-reference.jade | 4 ++--
public/docs/ts/latest/guide/template-syntax.jade | 10 +++++-----
6 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.html b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.html
index 91f7f416cd..9de98806d7 100644
--- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.html
+++ b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.html
@@ -10,10 +10,10 @@
-
+
Excellent choice!
-
+
No movie, sorry!
diff --git a/public/docs/_examples/cb-dynamic-form-deprecated/ts/app/dynamic-form-question.component.html b/public/docs/_examples/cb-dynamic-form-deprecated/ts/app/dynamic-form-question.component.html
index ceb2f41177..e580ee3027 100644
--- a/public/docs/_examples/cb-dynamic-form-deprecated/ts/app/dynamic-form-question.component.html
+++ b/public/docs/_examples/cb-dynamic-form-deprecated/ts/app/dynamic-form-question.component.html
@@ -4,10 +4,10 @@
-
-
+
{{opt.value}}
diff --git a/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html b/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html
index 3599c77271..cf19ebb137 100644
--- a/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html
+++ b/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html
@@ -9,8 +9,8 @@
- In Mission
- Ready
+ In Mission
+ Ready
Unknown
diff --git a/public/docs/_examples/template-syntax/ts/app/app.component.html b/public/docs/_examples/template-syntax/ts/app/app.component.html
index dcfd423e50..fbe3527362 100644
--- a/public/docs/_examples/template-syntax/ts/app/app.component.html
+++ b/public/docs/_examples/template-syntax/ts/app/app.component.html
@@ -498,18 +498,18 @@ bindon-ngModel
- Eenie
- Meanie
- Miney
- Moe
+ Eenie
+ Meanie
+ Miney
+ Moe
other
- Eenie
- Meanie
- Miney
- Moe
+ Eenie
+ Meanie
+ Miney
+ Moe
other
diff --git a/public/docs/ts/latest/cookbook/a1-a2-quick-reference.jade b/public/docs/ts/latest/cookbook/a1-a2-quick-reference.jade
index 8e95211b50..1e03e145d2 100644
--- a/public/docs/ts/latest/cookbook/a1-a2-quick-reference.jade
+++ b/public/docs/ts/latest/cookbook/a1-a2-quick-reference.jade
@@ -444,7 +444,7 @@ table(width="100%")
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngSwitch')(format="." )
:marked
In Angular 2, the `ngSwitch` directive works similarly.
- It displays an element whose `*ngSwitchWhen` matches the current `ngSwitch` expression value.
+ It displays an element whose `*ngSwitchCase` matches the current `ngSwitch` expression value.
In this example, if `favoriteHero` is not set, the `ngSwitch` value is `null`
and we see the `*ngSwitchDefault` paragraph, "Please enter ...".
@@ -452,7 +452,7 @@ table(width="100%")
If that method returns `true`, we see "Excellent choice!".
If that methods returns `false`, we see "No movie, sorry!".
- The (*) before `ngSwitchWhen` and `ngSwitchDefault` is required in this example.
+ The (*) before `ngSwitchCase` and `ngSwitchDefault` is required in this example.
For more information on the ngSwitch directive see [Template Syntax](../guide/template-syntax.html#ngSwitch).
:marked
diff --git a/public/docs/ts/latest/guide/template-syntax.jade b/public/docs/ts/latest/guide/template-syntax.jade
index 3414c3cdc0..9d4781d0da 100644
--- a/public/docs/ts/latest/guide/template-syntax.jade
+++ b/public/docs/ts/latest/guide/template-syntax.jade
@@ -1053,14 +1053,14 @@ block dart-no-truthy-falsey
:marked
Three collaborating directives are at work here:
1. `ngSwitch`: bound to an expression that returns the switch value
- 1. `ngSwitchWhen`: bound to an expression returning a match value
+ 1. `ngSwitchCase`: bound to an expression returning a match value
1. `ngSwitchDefault`: a marker attribute on the default element
.alert.is-critical
:marked
**Do *not*** put the asterisk (`*`) in front of `ngSwitch`. Use the property binding instead.
- **Do** put the asterisk (`*`) in front of `ngSwitchWhen` and `ngSwitchDefault`.
+ **Do** put the asterisk (`*`) in front of `ngSwitchCase` and `ngSwitchDefault`.
For more information, see [\* and <template>](#star-template).
@@ -1199,16 +1199,16 @@ block remember-the-brackets
:marked
### Expanding `*ngSwitch`
A similar transformation applies to `*ngSwitch`. We can de-sugar the syntax ourselves.
- Here's an example, first with `*ngSwitchWhen` and `*ngSwitchDefault` and then again with `` tags:
+ Here's an example, first with `*ngSwitchCase` and `*ngSwitchDefault` and then again with `` tags:
+makeExample('template-syntax/ts/app/app.component.html', 'NgSwitch-expanded')(format=".")
:marked
- The `*ngSwitchWhen` and `*ngSwitchDefault` expand in exactly the same manner as `*ngIf`,
+ The `*ngSwitchCase` and `*ngSwitchDefault` expand in exactly the same manner as `*ngIf`,
wrapping their former elements in `` tags.
Now we can see why the `ngSwitch` itself is not prefixed with an asterisk (*).
It does not define content. It's job is to control a collection of templates.
- In this case, it governs two sets of `NgSwitchWhen` and `NgSwitchDefault` directives.
+ In this case, it governs two sets of `ngSwitchCase` and `NgSwitchDefault` directives.
We should expect it to display the values of the selected template twice,
once for the (*) prefixed version and once for the expanded template version.
That's exactly what we see in this example:
From b049c1bcf4129caf25386df6fa660acbccbf7410 Mon Sep 17 00:00:00 2001
From: Patrice Chalin
Date: Fri, 17 Jun 2016 16:27:39 -0700
Subject: [PATCH 14/31] chore(guide/server-communication): fix indentation in
Jade
---
public/docs/ts/latest/guide/server-communication.jade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/docs/ts/latest/guide/server-communication.jade b/public/docs/ts/latest/guide/server-communication.jade
index 4025466ca8..2ce647af77 100644
--- a/public/docs/ts/latest/guide/server-communication.jade
+++ b/public/docs/ts/latest/guide/server-communication.jade
@@ -73,7 +73,7 @@ block system-config-of-http
SystemJS knows how to load services from the !{_Angular_http_library} when we import from the `@angular/http` module
because we registered that module name in the `system.config` file.
:marked
- Before we can use the `#{_Http}` client , we'll have to register it as a service provider with the Dependency Injection system.
+ Before we can use the `#{_Http}` client , we'll have to register it as a service provider with the Dependency Injection system.
.l-sub-section
:marked
Learn about providers in the [Dependency Injection](dependency-injection.html) chapter.
From 97fbda0d768874bf6964497debb9b37feba3b5dd Mon Sep 17 00:00:00 2001
From: Brandon Roberts
Date: Sun, 26 Jun 2016 12:13:44 -0500
Subject: [PATCH 15/31] docs(toh-6/ts): Upgraded http tutorial to use new
router
---
.../_examples/toh-6/ts/app/app.component.css | 2 +-
.../_examples/toh-6/ts/app/app.component.ts | 19 +++-------
.../docs/_examples/toh-6/ts/app/app.routes.ts | 30 ++++++++++++++++
.../toh-6/ts/app/dashboard.component.ts | 4 +--
.../toh-6/ts/app/hero-detail.component.ts | 35 +++++++++++--------
.../toh-6/ts/app/heroes.component.ts | 4 +--
public/docs/_examples/toh-6/ts/app/main.ts | 11 ++++--
public/docs/ts/latest/tutorial/toh-pt6.jade | 7 ++--
8 files changed, 73 insertions(+), 39 deletions(-)
create mode 100644 public/docs/_examples/toh-6/ts/app/app.routes.ts
diff --git a/public/docs/_examples/toh-6/ts/app/app.component.css b/public/docs/_examples/toh-6/ts/app/app.component.css
index f4e8082ea1..071e665767 100644
--- a/public/docs/_examples/toh-6/ts/app/app.component.css
+++ b/public/docs/_examples/toh-6/ts/app/app.component.css
@@ -24,6 +24,6 @@ nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
-nav a.router-link-active {
+nav a.active {
color: #039be5;
}
diff --git a/public/docs/_examples/toh-6/ts/app/app.component.ts b/public/docs/_examples/toh-6/ts/app/app.component.ts
index 22317d4403..2a1ff50ba3 100644
--- a/public/docs/_examples/toh-6/ts/app/app.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/app.component.ts
@@ -1,12 +1,9 @@
// #docplaster
// #docregion
-import { Component } from '@angular/core';
-import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
+import { Component } from '@angular/core';
+import { ROUTER_DIRECTIVES } from '@angular/router';
-import { DashboardComponent } from './dashboard.component';
-import { HeroesComponent } from './heroes.component';
-import { HeroDetailComponent } from './hero-detail.component';
-import { HeroService } from './hero.service';
+import { HeroService } from './hero.service';
@Component({
selector: 'my-app',
@@ -14,23 +11,17 @@ import { HeroService } from './hero.service';
template: `
{{title}}
- Dashboard
- Heroes
+ Dashboard
+ Heroes
`,
styleUrls: ['app/app.component.css'],
directives: [ROUTER_DIRECTIVES],
providers: [
- ROUTER_PROVIDERS,
HeroService,
]
})
-@RouteConfig([
- { path: '/dashboard', name: 'Dashboard', component: DashboardComponent, useAsDefault: true },
- { path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent },
- { path: '/heroes', name: 'Heroes', component: HeroesComponent }
-])
export class AppComponent {
title = 'Tour of Heroes';
}
diff --git a/public/docs/_examples/toh-6/ts/app/app.routes.ts b/public/docs/_examples/toh-6/ts/app/app.routes.ts
new file mode 100644
index 0000000000..b299102385
--- /dev/null
+++ b/public/docs/_examples/toh-6/ts/app/app.routes.ts
@@ -0,0 +1,30 @@
+// #docregion
+import { provideRouter, RouterConfig } from '@angular/router';
+
+import { DashboardComponent } from './dashboard.component';
+import { HeroesComponent } from './heroes.component';
+import { HeroDetailComponent } from './hero-detail.component';
+
+export const routes: RouterConfig = [
+ {
+ path: '',
+ redirectTo: '/dashboard',
+ terminal: true
+ },
+ {
+ path: 'dashboard',
+ component: DashboardComponent
+ },
+ {
+ path: 'detail/:id',
+ component: HeroDetailComponent
+ },
+ {
+ path: 'heroes',
+ component: HeroesComponent
+ }
+];
+
+export const APP_ROUTER_PROVIDERS = [
+ provideRouter(routes)
+];
diff --git a/public/docs/_examples/toh-6/ts/app/dashboard.component.ts b/public/docs/_examples/toh-6/ts/app/dashboard.component.ts
index 8ca1e3a2e2..08ffecc0ea 100644
--- a/public/docs/_examples/toh-6/ts/app/dashboard.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/dashboard.component.ts
@@ -1,7 +1,7 @@
// #docplaster
// #docregion
import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router-deprecated';
+import { Router } from '@angular/router';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@@ -26,7 +26,7 @@ export class DashboardComponent implements OnInit {
}
gotoDetail(hero: Hero) {
- let link = ['HeroDetail', { id: hero.id }];
+ let link = ['/detail', hero.id];
this.router.navigate(link);
}
}
diff --git a/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts
index 8da8978a08..85d722999e 100644
--- a/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts
@@ -1,9 +1,9 @@
// #docplaster
// #docregion, variables-imports
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { Component, EventEmitter, Input, OnInit, OnDestroy, Output } from '@angular/core';
// #enddocregion variables-imports
-import { RouteParams } from '@angular/router-deprecated';
+import { ActivatedRoute } from '@angular/router';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@@ -14,31 +14,39 @@ import { HeroService } from './hero.service';
styleUrls: ['app/hero-detail.component.css']
})
// #docregion variables-imports
-export class HeroDetailComponent implements OnInit {
+export class HeroDetailComponent implements OnInit, OnDestroy {
@Input() hero: Hero;
@Output() close = new EventEmitter();
error: any;
+ sub: any;
navigated = false; // true if navigated here
// #enddocregion variables-imports
constructor(
private heroService: HeroService,
- private routeParams: RouteParams) {
+ private route: ActivatedRoute) {
}
// #docregion ngOnInit
ngOnInit() {
- if (this.routeParams.get('id') !== null) {
- let id = +this.routeParams.get('id');
- this.navigated = true;
- this.heroService.getHero(id)
- .then(hero => this.hero = hero);
- } else {
- this.navigated = false;
- this.hero = new Hero();
- }
+ this.sub = this.route.params.subscribe(params => {
+ if (params['id'] !== undefined) {
+ let id = +params['id'];
+ this.navigated = true;
+ this.heroService.getHero(id)
+ .then(hero => this.hero = hero);
+ } else {
+ this.navigated = false;
+ this.hero = new Hero();
+ }
+ });
}
// #enddocregion ngOnInit
+
+ ngOnDestroy() {
+ this.sub.unsubscribe();
+ }
+
// #docregion save
save() {
this.heroService
@@ -57,4 +65,3 @@ export class HeroDetailComponent implements OnInit {
}
// #enddocregion goBack
}
-
diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.ts b/public/docs/_examples/toh-6/ts/app/heroes.component.ts
index 1573b96be6..3bf618f5bd 100644
--- a/public/docs/_examples/toh-6/ts/app/heroes.component.ts
+++ b/public/docs/_examples/toh-6/ts/app/heroes.component.ts
@@ -1,6 +1,6 @@
// #docregion
import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router-deprecated';
+import { Router } from '@angular/router';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@@ -68,6 +68,6 @@ export class HeroesComponent implements OnInit {
}
gotoDetail() {
- this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
+ this.router.navigate(['/detail', this.selectedHero.id]);
}
}
diff --git a/public/docs/_examples/toh-6/ts/app/main.ts b/public/docs/_examples/toh-6/ts/app/main.ts
index 958b9a8c69..948e2ca5ba 100644
--- a/public/docs/_examples/toh-6/ts/app/main.ts
+++ b/public/docs/_examples/toh-6/ts/app/main.ts
@@ -11,16 +11,21 @@ import { InMemoryDataService } from './in-memory-data.service';
import { bootstrap } from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '@angular/http';
-import { AppComponent } from './app.component';
+import { AppComponent } from './app.component';
+import { APP_ROUTER_PROVIDERS } from './app.routes';
// #enddocregion v1, final
/*
// #docregion v1
-bootstrap(AppComponent, [ HTTP_PROVIDERS ]);
+bootstrap(AppComponent, [
+ APP_ROUTER_PROVIDERS,
+ HTTP_PROVIDERS
+]);
// #enddocregion v1
- */
+*/
// #docregion final
bootstrap(AppComponent, [
+ APP_ROUTER_PROVIDERS,
HTTP_PROVIDERS,
{ provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
{ provide: SEED_DATA, useClass: InMemoryDataService } // in-mem server data
diff --git a/public/docs/ts/latest/tutorial/toh-pt6.jade b/public/docs/ts/latest/tutorial/toh-pt6.jade
index 3a1214bb17..4b25b30b86 100644
--- a/public/docs/ts/latest/tutorial/toh-pt6.jade
+++ b/public/docs/ts/latest/tutorial/toh-pt6.jade
@@ -7,7 +7,7 @@ block includes
- var _Angular_http_library = 'Angular HTTP library'
- var _HTTP_PROVIDERS = 'HTTP_PROVIDERS'
- var _JSON_stringify = 'JSON.stringify'
-
+
:marked
# Getting and Saving Data with HTTP
@@ -250,8 +250,8 @@ block hero-detail-comp-updates
:marked
### Add/Edit in the *HeroDetailComponent*
- 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 `HeroDetailComponent` with a few tweaks.
+ 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 `HeroDetailComponent` 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.
@@ -373,6 +373,7 @@ block filetree
.children
.file app.component.ts
.file app.component.css
+ .file app.routes.ts
.file dashboard.component.css
.file dashboard.component.html
.file dashboard.component.ts
From f06398cd892ad82d3460bcd2df5dadc3bf5ee184 Mon Sep 17 00:00:00 2001
From: Patrice Chalin
Date: Tue, 28 Jun 2016 13:12:49 -0700
Subject: [PATCH 16/31] docs(toh-6/dart): first edition of prose and example
code (#1687)
* docs(toh-6/dart): first edition of prose and example code
NOTE: this PR depends on #1686.
Dart prose and example match TS except that:
- No child-to-parent event emission occurs.
- Support for Add Hero is added as an unconditional feature of the
Heroes view.
- http `_post` takes only a name
- http `delete` takes only a hero id.
- The Dart in-memory-data-service has been dropped in favor of an
implementation based on the "standard" `http.testing.MockClient` class.
* post-review changes
---
.../docs/_examples/toh-6/dart/.docsync.json | 5 +
.../toh-6/dart/lib/app_component.css | 29 ++++
.../toh-6/dart/lib/app_component.dart | 45 ++++++
.../toh-6/dart/lib/dashboard_component.css | 61 ++++++++
.../toh-6/dart/lib/dashboard_component.dart | 47 ++++++
.../toh-6/dart/lib/dashboard_component.html | 11 ++
.../docs/_examples/toh-6/dart/lib/hero.dart | 14 ++
.../toh-6/dart/lib/hero_detail_component.css | 30 ++++
.../toh-6/dart/lib/hero_detail_component.dart | 61 ++++++++
.../toh-6/dart/lib/hero_detail_component.html | 15 ++
.../toh-6/dart/lib/hero_service.dart | 91 +++++++++++
.../toh-6/dart/lib/heroes_component.css | 59 ++++++++
.../toh-6/dart/lib/heroes_component.dart | 69 +++++++++
.../toh-6/dart/lib/heroes_component.html | 31 ++++
.../dart/lib/in_memory_data_service.dart | 64 ++++++++
public/docs/_examples/toh-6/dart/pubspec.yaml | 28 ++++
.../docs/_examples/toh-6/dart/web/index.html | 18 +++
.../docs/_examples/toh-6/dart/web/main.dart | 29 ++++
.../docs/_examples/toh-6/dart/web/sample.css | 7 +
public/docs/dart/latest/tutorial/toh-pt6.jade | 142 +++++++++++++++++-
20 files changed, 855 insertions(+), 1 deletion(-)
create mode 100644 public/docs/_examples/toh-6/dart/.docsync.json
create mode 100644 public/docs/_examples/toh-6/dart/lib/app_component.css
create mode 100644 public/docs/_examples/toh-6/dart/lib/app_component.dart
create mode 100644 public/docs/_examples/toh-6/dart/lib/dashboard_component.css
create mode 100644 public/docs/_examples/toh-6/dart/lib/dashboard_component.dart
create mode 100644 public/docs/_examples/toh-6/dart/lib/dashboard_component.html
create mode 100644 public/docs/_examples/toh-6/dart/lib/hero.dart
create mode 100644 public/docs/_examples/toh-6/dart/lib/hero_detail_component.css
create mode 100644 public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart
create mode 100644 public/docs/_examples/toh-6/dart/lib/hero_detail_component.html
create mode 100644 public/docs/_examples/toh-6/dart/lib/hero_service.dart
create mode 100644 public/docs/_examples/toh-6/dart/lib/heroes_component.css
create mode 100644 public/docs/_examples/toh-6/dart/lib/heroes_component.dart
create mode 100644 public/docs/_examples/toh-6/dart/lib/heroes_component.html
create mode 100644 public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart
create mode 100644 public/docs/_examples/toh-6/dart/pubspec.yaml
create mode 100644 public/docs/_examples/toh-6/dart/web/index.html
create mode 100644 public/docs/_examples/toh-6/dart/web/main.dart
create mode 100644 public/docs/_examples/toh-6/dart/web/sample.css
diff --git a/public/docs/_examples/toh-6/dart/.docsync.json b/public/docs/_examples/toh-6/dart/.docsync.json
new file mode 100644
index 0000000000..29f01f6648
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/.docsync.json
@@ -0,0 +1,5 @@
+{
+ "title": "Tour of Heroes: HTTP",
+ "docPart": "tutorial",
+ "docHref": "toh-pt6.html"
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/app_component.css b/public/docs/_examples/toh-6/dart/lib/app_component.css
new file mode 100644
index 0000000000..f4e8082ea1
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/app_component.css
@@ -0,0 +1,29 @@
+/* #docregion */
+h1 {
+ font-size: 1.2em;
+ color: #999;
+ margin-bottom: 0;
+}
+h2 {
+ font-size: 2em;
+ margin-top: 0;
+ padding-top: 0;
+}
+nav a {
+ padding: 5px 10px;
+ text-decoration: none;
+ margin-top: 10px;
+ display: inline-block;
+ background-color: #eee;
+ border-radius: 4px;
+}
+nav a:visited, a:link {
+ color: #607D8B;
+}
+nav a:hover {
+ color: #039be5;
+ background-color: #CFD8DC;
+}
+nav a.router-link-active {
+ color: #039be5;
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/app_component.dart b/public/docs/_examples/toh-6/dart/lib/app_component.dart
new file mode 100644
index 0000000000..ecf2bf4f3c
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/app_component.dart
@@ -0,0 +1,45 @@
+// #docplaster
+// #docregion
+import 'package:angular2/core.dart';
+import 'package:angular2/router.dart';
+
+import 'package:angular2_tour_of_heroes/heroes_component.dart';
+import 'package:angular2_tour_of_heroes/hero_service.dart';
+import 'package:angular2_tour_of_heroes/dashboard_component.dart';
+// #docregion hero-detail-import
+import 'package:angular2_tour_of_heroes/hero_detail_component.dart';
+// #enddocregion hero-detail-import
+
+@Component(
+ selector: 'my-app',
+ // #docregion template
+ template: '''
+ {{title}}
+
+ Dashboard
+ Heroes
+
+ ''',
+ // #enddocregion template
+ // #docregion style-urls
+ styleUrls: const ['app_component.css'],
+ // #enddocregion style-urls
+ directives: const [ROUTER_DIRECTIVES],
+ providers: const [HeroService, ROUTER_PROVIDERS])
+@RouteConfig(const [
+ // #docregion dashboard-route
+ const Route(
+ path: '/dashboard',
+ name: 'Dashboard',
+ component: DashboardComponent,
+ useAsDefault: true),
+ // #enddocregion dashboard-route
+ // #docregion hero-detail-route
+ const Route(
+ path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent),
+ // #enddocregion hero-detail-route
+ const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
+])
+class AppComponent {
+ String title = 'Tour of Heroes';
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.css b/public/docs/_examples/toh-6/dart/lib/dashboard_component.css
new file mode 100644
index 0000000000..f6263074f0
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.css
@@ -0,0 +1,61 @@
+/* #docregion */
+[class*='col-'] {
+ float: left;
+}
+*, *:after, *:before {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+h3 {
+ text-align: center; margin-bottom: 0;
+}
+[class*='col-'] {
+ padding-right: 20px;
+ padding-bottom: 20px;
+}
+[class*='col-']:last-of-type {
+ padding-right: 0;
+}
+.grid {
+ margin: 0;
+}
+.col-1-4 {
+ width: 25%;
+}
+.module {
+ padding: 20px;
+ text-align: center;
+ color: #eee;
+ max-height: 120px;
+ min-width: 120px;
+ background-color: #607D8B;
+ border-radius: 2px;
+}
+h4 {
+ position: relative;
+}
+.module:hover {
+ background-color: #EEE;
+ cursor: pointer;
+ color: #607d8b;
+}
+.grid-pad {
+ padding: 10px 0;
+}
+.grid-pad > [class*='col-']:last-of-type {
+ padding-right: 20px;
+}
+@media (max-width: 600px) {
+ .module {
+ font-size: 10px;
+ max-height: 75px; }
+}
+@media (max-width: 1024px) {
+ .grid {
+ margin: 0;
+ }
+ .module {
+ min-width: 60px;
+ }
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart b/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart
new file mode 100644
index 0000000000..ff0fb8c0d1
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart
@@ -0,0 +1,47 @@
+// #docplaster
+// #docregion
+import 'dart:async';
+
+import 'package:angular2/core.dart';
+// #docregion import-router
+import 'package:angular2/router.dart';
+// #enddocregion import-router
+
+import 'hero.dart';
+import 'hero_service.dart';
+
+@Component(
+ selector: 'my-dashboard',
+ // #docregion template-url
+ templateUrl: 'dashboard_component.html',
+ // #enddocregion template-url
+ // #docregion css
+ styleUrls: const ['dashboard_component.css']
+ // #enddocregion css
+ )
+// #docregion component
+class DashboardComponent implements OnInit {
+ List heroes;
+
+ // #docregion ctor
+ final Router _router;
+ final HeroService _heroService;
+
+ DashboardComponent(this._heroService, this._router);
+
+ // #enddocregion ctor
+
+ Future ngOnInit() async {
+ heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
+ }
+
+ // #docregion goto-detail
+ void gotoDetail(Hero hero) {
+ var link = [
+ 'HeroDetail',
+ {'id': hero.id.toString()}
+ ];
+ _router.navigate(link);
+ }
+// #enddocregion goto-detail
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.html b/public/docs/_examples/toh-6/dart/lib/dashboard_component.html
new file mode 100644
index 0000000000..7133c10ada
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.html
@@ -0,0 +1,11 @@
+
+Top Heroes
+
diff --git a/public/docs/_examples/toh-6/dart/lib/hero.dart b/public/docs/_examples/toh-6/dart/lib/hero.dart
new file mode 100644
index 0000000000..bc9a33b8d9
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/hero.dart
@@ -0,0 +1,14 @@
+// #docregion
+class Hero {
+ final int id;
+ String name;
+
+ Hero(this.id, this.name);
+
+ factory Hero.fromJson(Map hero) =>
+ new Hero(_toInt(hero['id']), hero['name']);
+
+ Map toJson() => {'id': id, 'name': name};
+}
+
+int _toInt(id) => id is int ? id : int.parse(id);
diff --git a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.css b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.css
new file mode 100644
index 0000000000..ab2437efd8
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.css
@@ -0,0 +1,30 @@
+/* #docregion */
+label {
+ display: inline-block;
+ width: 3em;
+ margin: .5em 0;
+ color: #607D8B;
+ font-weight: bold;
+}
+input {
+ height: 2em;
+ font-size: 1em;
+ padding-left: .4em;
+}
+button {
+ margin-top: 20px;
+ font-family: Arial;
+ background-color: #eee;
+ border: none;
+ padding: 5px 10px;
+ border-radius: 4px;
+ cursor: pointer; cursor: hand;
+}
+button:hover {
+ background-color: #cfd8dc;
+}
+button:disabled {
+ background-color: #eee;
+ color: #ccc;
+ cursor: auto;
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart
new file mode 100644
index 0000000000..39f9f531f5
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart
@@ -0,0 +1,61 @@
+// #docplaster
+// #docregion , v2
+import 'dart:async';
+import 'dart:html';
+
+// #docregion import-oninit
+import 'package:angular2/core.dart';
+// #enddocregion import-oninit
+// #docregion import-route-params
+import 'package:angular2/router.dart';
+// #enddocregion import-route-params
+
+import 'hero.dart';
+// #docregion import-hero-service
+import 'hero_service.dart';
+// #enddocregion import-hero-service
+
+// #docregion extract-template
+@Component(
+ selector: 'my-hero-detail',
+ // #docregion template-url
+ templateUrl: 'hero_detail_component.html',
+ // #enddocregion template-url, v2
+ styleUrls: const ['hero_detail_component.css']
+ // #docregion v2
+ )
+// #enddocregion extract-template
+// #docregion implement
+class HeroDetailComponent implements OnInit {
+ // #enddocregion implement
+ Hero hero;
+ // #docregion ctor
+ final HeroService _heroService;
+ final RouteParams _routeParams;
+
+ HeroDetailComponent(this._heroService, this._routeParams);
+ // #enddocregion ctor
+
+ // #docregion ng-oninit
+ Future ngOnInit() async {
+ // #docregion get-id
+ var idString = _routeParams.get('id');
+ var id = int.parse(idString, onError: (_) => null);
+ // #enddocregion get-id
+ if (id != null) hero = await (_heroService.getHero(id));
+ }
+ // #enddocregion ng-oninit
+
+ // #docregion save
+ Future save() async {
+ await _heroService.save(hero);
+ goBack();
+ }
+ // #enddocregion save
+
+ // #docregion go-back
+ void goBack() {
+ window.history.back();
+ }
+ // #enddocregion go-back
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html
new file mode 100644
index 0000000000..d15546af74
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html
@@ -0,0 +1,15 @@
+
+
+
+
{{hero.name}} details!
+
+ id: {{hero.id}}
+
+ name:
+
+
+
Back
+
+
Save
+
+
diff --git a/public/docs/_examples/toh-6/dart/lib/hero_service.dart b/public/docs/_examples/toh-6/dart/lib/hero_service.dart
new file mode 100644
index 0000000000..7a15c6473f
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/hero_service.dart
@@ -0,0 +1,91 @@
+// #docregion
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:angular2/core.dart';
+import 'package:http/http.dart';
+
+import 'hero.dart';
+
+@Injectable()
+class HeroService {
+ // #docregion post
+ static final _headers = {'Content-Type': 'application/json'};
+ // #enddocregion post
+ // #docregion getHeroes
+ static const _heroesUrl = 'app/heroes'; // URL to web API
+
+ final Client _http;
+
+ HeroService(this._http);
+
+ Future> getHeroes() async {
+ try {
+ final response = await _http.get(_heroesUrl);
+ final heroes = _extractData(response)
+ .map((value) => new Hero.fromJson(value))
+ .toList();
+ return heroes;
+ // #docregion catch
+ } catch (e) {
+ throw _handleError(e);
+ }
+ // #enddocregion catch
+ }
+
+ // #docregion extract-data
+ dynamic _extractData(Response resp) => JSON.decode(resp.body)['data'];
+ // #enddocregion extract-data, getHeroes
+
+ Future getHero(int id) async =>
+ (await getHeroes()).firstWhere((hero) => hero.id == id);
+
+ // #docregion save
+ Future save(dynamic heroOrName) =>
+ heroOrName is Hero ? _put(heroOrName) : _post(heroOrName);
+ // #enddocregion save
+
+ // #docregion handleError
+ Exception _handleError(dynamic e) {
+ print(e); // for demo purposes only
+ return new Exception('Server error; cause: $e');
+ }
+ // #enddocregion handleError
+
+ // #docregion post
+ Future _post(String name) async {
+ try {
+ final response = await _http.post(_heroesUrl,
+ headers: _headers, body: JSON.encode({'name': name}));
+ return new Hero.fromJson(_extractData(response));
+ } catch (e) {
+ throw _handleError(e);
+ }
+ }
+ // #enddocregion post
+
+ // #docregion put
+ Future _put(Hero hero) async {
+ try {
+ var url = '$_heroesUrl/${hero.id}';
+ final response =
+ await _http.put(url, headers: _headers, body: JSON.encode(hero));
+ return new Hero.fromJson(_extractData(response));
+ } catch (e) {
+ throw _handleError(e);
+ }
+ }
+ // #enddocregion put
+
+ // #docregion delete
+ Future delete(int id) async {
+ try {
+ var url = '$_heroesUrl/$id';
+ await _http.delete(url, headers: _headers);
+ } catch (e) {
+ throw _handleError(e);
+ }
+ }
+ // #enddocregion delete
+
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/heroes_component.css b/public/docs/_examples/toh-6/dart/lib/heroes_component.css
new file mode 100644
index 0000000000..35e45af98d
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/heroes_component.css
@@ -0,0 +1,59 @@
+.selected {
+ background-color: #CFD8DC !important;
+ color: white;
+}
+.heroes {
+ margin: 0 0 2em 0;
+ list-style-type: none;
+ padding: 0;
+ width: 15em;
+}
+.heroes li {
+ cursor: pointer;
+ position: relative;
+ left: 0;
+ background-color: #EEE;
+ margin: .5em;
+ padding: .3em 0;
+ height: 1.6em;
+ border-radius: 4px;
+}
+.heroes li:hover {
+ color: #607D8B;
+ background-color: #DDD;
+ left: .1em;
+}
+.heroes li.selected:hover {
+ background-color: #BBD8DC !important;
+ color: white;
+}
+.heroes .text {
+ position: relative;
+ top: -3px;
+}
+.heroes .badge {
+ display: inline-block;
+ font-size: small;
+ color: white;
+ padding: 0.8em 0.7em 0 0.7em;
+ background-color: #607D8B;
+ line-height: 1em;
+ position: relative;
+ left: -1px;
+ top: -4px;
+ height: 1.8em;
+ margin-right: .8em;
+ border-radius: 4px 0 0 4px;
+}
+button {
+ font-family: Arial;
+ background-color: #eee;
+ border: none;
+ padding: 5px 10px;
+ border-radius: 4px;
+ cursor: pointer;
+ cursor: hand;
+}
+button:hover {
+ background-color: #cfd8dc;
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/heroes_component.dart b/public/docs/_examples/toh-6/dart/lib/heroes_component.dart
new file mode 100644
index 0000000000..4cfc0c427e
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/heroes_component.dart
@@ -0,0 +1,69 @@
+// #docplaster
+// #docregion
+import 'dart:async';
+
+import 'package:angular2/core.dart';
+import 'package:angular2/router.dart';
+
+import 'hero.dart';
+import 'hero_detail_component.dart';
+import 'hero_service.dart';
+
+@Component(
+ selector: 'my-heroes',
+ templateUrl: 'heroes_component.html',
+ styleUrls: const ['heroes_component.css'],
+ directives: const [HeroDetailComponent])
+class HeroesComponent implements OnInit {
+ final Router _router;
+ final HeroService _heroService;
+ List heroes;
+ Hero selectedHero;
+ // #docregion error
+ String errorMessage;
+ // #enddocregion error
+
+ HeroesComponent(this._heroService, this._router);
+
+ // #docregion addHero
+ Future addHero(String name) async {
+ name = name.trim();
+ if (name.isEmpty) return;
+ try {
+ heroes.add(await _heroService.save(name));
+ } catch (e) {
+ errorMessage = e.toString();
+ }
+ }
+ // #enddocregion addHero
+
+ // #docregion deleteHero
+ Future deleteHero(int id, event) async {
+ try {
+ event.stopPropagation();
+ await _heroService.delete(id);
+ heroes.removeWhere((hero) => hero.id == id);
+ if (selectedHero?.id == id) selectedHero = null;
+ } catch (e) {
+ errorMessage = e.toString();
+ }
+ }
+ // #enddocregion deleteHero
+
+ Future getHeroes() async {
+ heroes = await _heroService.getHeroes();
+ }
+
+ void ngOnInit() {
+ getHeroes();
+ }
+
+ void onSelect(Hero hero) {
+ selectedHero = hero;
+ }
+
+ Future gotoDetail() => _router.navigate([
+ 'HeroDetail',
+ {'id': selectedHero.id.toString()}
+ ]);
+}
diff --git a/public/docs/_examples/toh-6/dart/lib/heroes_component.html b/public/docs/_examples/toh-6/dart/lib/heroes_component.html
new file mode 100644
index 0000000000..98f3db8442
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/heroes_component.html
@@ -0,0 +1,31 @@
+
+
+My Heroes
+
+{{errorMessage}}
+
+ Name:
+
+ Add New Hero
+
+
+
+
+
+ {{hero.id}} {{hero.name}}
+
+ x
+
+
+
+
+
+
+
+ {{selectedHero.name | uppercase}} is my hero
+
+
+ View Details
+
diff --git a/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart b/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart
new file mode 100644
index 0000000000..86aad3de53
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart
@@ -0,0 +1,64 @@
+// #docregion
+import 'dart:async';
+import 'dart:convert';
+
+// #docregion init
+import 'package:angular2/core.dart';
+import 'package:http/http.dart';
+import 'package:http/testing.dart';
+
+import 'hero.dart';
+
+@Injectable()
+class InMemoryDataService extends MockClient {
+ static final _initialHeroes = [
+ {'id': 11, 'name': 'Mr. Nice'},
+ {'id': 12, 'name': 'Narco'},
+ {'id': 13, 'name': 'Bombasto'},
+ {'id': 14, 'name': 'Celeritas'},
+ {'id': 15, 'name': 'Magneta'},
+ {'id': 16, 'name': 'RubberMan'},
+ {'id': 17, 'name': 'Dynama2'},
+ {'id': 18, 'name': 'Dr IQ'},
+ {'id': 19, 'name': 'Magma'},
+ {'id': 20, 'name': 'Tornado'}
+ ];
+ // #enddocregion init
+
+ static final List _heroesDb =
+ _initialHeroes.map((json) => new Hero.fromJson(json)).toList();
+ static int _nextId = 21;
+
+ static Future _handler(Request request) async {
+ var data;
+ switch (request.method) {
+ case 'GET':
+ data = _heroesDb;
+ break;
+ case 'POST':
+ var name = JSON.decode(request.body)['name'];
+ var newHero = new Hero(_nextId++, name);
+ _heroesDb.add(newHero);
+ data = newHero;
+ break;
+ case 'PUT':
+ var heroChanges = new Hero.fromJson(JSON.decode(request.body));
+ var targetHero = _heroesDb.firstWhere((h) => h.id == heroChanges.id);
+ targetHero.name = heroChanges.name;
+ data = targetHero;
+ break;
+ case 'DELETE':
+ var id = int.parse(request.url.pathSegments.last);
+ _heroesDb.removeWhere((hero) => hero.id == id);
+ // No data, so leave it as null.
+ break;
+ default:
+ throw 'Unimplemented HTTP method ${request.method}';
+ }
+ return new Response(JSON.encode({'data': data}), 200,
+ headers: {'content-type': 'application/json'});
+ }
+
+ InMemoryDataService() : super(_handler);
+ // #docregion init
+}
diff --git a/public/docs/_examples/toh-6/dart/pubspec.yaml b/public/docs/_examples/toh-6/dart/pubspec.yaml
new file mode 100644
index 0000000000..574758d902
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/pubspec.yaml
@@ -0,0 +1,28 @@
+# #docregion , additions
+name: angular2_tour_of_heroes
+ # #enddocregion additions
+description: Tour of Heroes
+version: 0.0.1
+environment:
+ sdk: '>=1.13.0 <2.0.0'
+ # #docregion additions
+dependencies:
+ angular2: 2.0.0-beta.17
+ # #enddocregion additions
+ browser: ^0.10.0
+ dart_to_js_script_rewriter: ^1.0.1
+ # #docregion additions
+ http: ^0.11.0
+transformers:
+- angular2:
+ # #enddocregion additions
+ platform_directives:
+ - 'package:angular2/common.dart#COMMON_DIRECTIVES'
+ platform_pipes:
+ - 'package:angular2/common.dart#COMMON_PIPES'
+ # #docregion additions
+ entry_points: web/main.dart
+ resolved_identifiers:
+ BrowserClient: 'package:http/browser_client.dart'
+ Client: 'package:http/http.dart'
+- dart_to_js_script_rewriter
diff --git a/public/docs/_examples/toh-6/dart/web/index.html b/public/docs/_examples/toh-6/dart/web/index.html
new file mode 100644
index 0000000000..be8fb7b42e
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/web/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Angular 2 Tour of Heroes
+
+
+
+
+
+
+
+
+
+ Loading...
+
+
diff --git a/public/docs/_examples/toh-6/dart/web/main.dart b/public/docs/_examples/toh-6/dart/web/main.dart
new file mode 100644
index 0000000000..1075856c61
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/web/main.dart
@@ -0,0 +1,29 @@
+// #docplaster
+// #docregion final
+// #docregion v1
+import 'package:angular2/core.dart';
+import 'package:angular2/platform/browser.dart';
+import 'package:angular2_tour_of_heroes/app_component.dart';
+// #enddocregion v1
+import 'package:http/http.dart';
+import 'package:angular2_tour_of_heroes/in_memory_data_service.dart';
+
+void main() {
+ bootstrap(AppComponent,
+ const [const Provider(Client, useClass: InMemoryDataService)]);
+}
+// #enddocregion final
+/*
+// #docregion v1
+import 'package:http/browser_client.dart';
+
+void main() {
+ bootstrap(AppComponent, [
+ provide(BrowserClient, useFactory: () => new BrowserClient(), deps: [])
+ ]);
+ // Simplify bootstrap provider list to [BrowserClient]
+ // once there is a fix for:
+ // https://github.com/angular/angular/issues/9673
+}
+// #enddocregion v1
+*/
diff --git a/public/docs/_examples/toh-6/dart/web/sample.css b/public/docs/_examples/toh-6/dart/web/sample.css
new file mode 100644
index 0000000000..6bbf5de8b7
--- /dev/null
+++ b/public/docs/_examples/toh-6/dart/web/sample.css
@@ -0,0 +1,7 @@
+/* #docregion */
+.error {color:red;}
+button.delete-button {
+ float:right;
+ background-color: gray !important;
+ color:white;
+}
diff --git a/public/docs/dart/latest/tutorial/toh-pt6.jade b/public/docs/dart/latest/tutorial/toh-pt6.jade
index 6778b6af28..694975a368 100644
--- a/public/docs/dart/latest/tutorial/toh-pt6.jade
+++ b/public/docs/dart/latest/tutorial/toh-pt6.jade
@@ -1 +1,141 @@
-!= partial("../../../_includes/_ts-temp")
+extends ../../../ts/latest/tutorial/toh-pt6.jade
+
+block includes
+ include ../_util-fns
+ - var _Http = 'BrowserClient';
+ - var _Angular_Http = 'Dart BrowserClient'
+ - var _httpUrl = 'https://pub.dartlang.org/packages/http'
+ - var _Angular_http_library = 'Dart http package'
+ - var _HTTP_PROVIDERS = 'BrowserClient'
+ - var _JSON_stringify = 'JSON.encode'
+
+block start-server-and-watch
+ :marked
+ ### Keep the app compiling and running
+ Open a terminal/console window.
+ Start the Dart compiler, watch for changes, and start our server by entering the command:
+
+ code-example(language="bash").
+ pub serve
+
+block http-library
+ :marked
+ We'll be using the !{_Angular_http_library}'s
+ `BrowserClient` class to communicate with a server.
+
+ ### Pubspec updates
+
+ We need to add a package dependency for the !{_Angular_http_library}.
+
+ We also need to add a `resolved_identifiers` entry, to inform the [angular2
+ transformer][ng2x] that we'll be using `BrowserClient`. (For an explanation of why
+ this extra configuration is needed, see the [HTTP client chapter][guide-http].) We'll
+ also need to use `Client` from http, so let's add that now as well.
+
+ Update `pubspec.yaml` to look like this (additions are highlighted):
+
+ [guide-http]: ../guide/server-communication.html#!#http-providers
+ [ng2x]: https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer
+
+ - var stylePattern = { pnk: /(http.*|resolved_identifiers:|Browser.*|Client.*)/gm };
+ +makeExcerpt('pubspec.yaml', 'additions', null, stylePattern)
+
+block http-providers
+ :marked
+ Before our app can use `#{_Http}`, we have to register it as a service provider.
+
+block backend
+ :marked
+ We want to replace `BrowserClient`, the service that talks to the remote server,
+ with the in-memory web API service.
+ Our in-memory web API service, shown below, is implemented using the
+ `http` library `MockClient` class.
+ All `http` client implementations share a common `Client` interface, so
+ we'll have our app use the `Client` type so that we can freely switch between
+ implementations.
+
+block dont-be-distracted-by-backend-subst
+ //- N/A
+
+block get-heroes-details
+ :marked
+ To get the list of heroes, we first make an asynchronous call to
+ `http.get()`. Then we use the `_extractData` helper method to decode the
+ response payload (`body`).
+
+block hero-detail-comp-extra-imports-and-vars
+ //- N/A
+
+block hero-detail-comp-updates
+ :marked
+ ### Edit in the *HeroDetailComponent*
+
+ We already have `HeroDetailComponent` for viewing details about a specific hero.
+ Supporting edit functionality is a natural extension of the detail view,
+ so we are able to reuse `HeroDetailComponent` with a few tweaks.
+
+block hero-detail-comp-save-and-goback
+ //- N/A
+
+block add-new-hero-via-detail-comp
+ //- N/A
+
+block heroes-comp-directives
+ //- N/A
+
+block heroes-comp-add
+ //- N/A
+
+block review
+ //- Not showing animated gif due to differences between TS and Dart implementations.
+
+block filetree
+ .filetree
+ .file angular2-tour-of-heroes
+ .children
+ .file lib
+ .children
+ .file app_component.dart
+ .file app_component.css
+ .file dashboard_component.css
+ .file dashboard_component.html
+ .file dashboard_component.dart
+ .file hero.dart
+ .file hero_detail_component.css
+ .file hero_detail_component.html
+ .file hero_detail_component.dart
+ .file hero_service.dart
+ .file heroes_component.css
+ .file heroes_component.html
+ .file heroes_component.dart
+ .file main.dart
+ .file in_memory_data_service.dart (new)
+ .file web
+ .children
+ .file main.dart
+ .file index.html
+ .file sample.css (new)
+ .file styles.css
+ .file pubspec.yaml
+
+block file-summary
+ +makeTabs(
+ `toh-6/dart/lib/hero.dart,
+ toh-6/dart/lib/hero_detail_component.dart,
+ toh-6/dart/lib/hero_detail_component.html,
+ toh-6/dart/lib/hero_service.dart,
+ toh-6/dart/lib/heroes_component.dart,
+ toh-6/dart/web/index.html,
+ toh-6/dart/web/main.dart,
+ toh-6/dart/web/sample.css`,
+ `,,,,,,final,`,
+ `lib/hero.dart,
+ lib/hero_detail_component.dart,
+ lib/hero_detail_component.html,
+ lib/hero_service.dart,
+ lib/heroes_component.dart,
+ web/index.html,
+ web/main.dart,
+ web/sample.css`)
+
+ +makeExample('pubspec.yaml')
From eda47f64e8ea3b807de5f7b8acc49d7f1811f21e Mon Sep 17 00:00:00 2001
From: Patrice Chalin
Date: Tue, 28 Jun 2016 13:13:58 -0700
Subject: [PATCH 17/31] docs(guide/lifecycle-hooks): follow-up to #1654 (#1768)
Mainly Dart-side review, following #1654:
- Updates to follow style guide
- Enabled e2e tests
- Fixes to ensure tests pass: in after_view_component.dart and
after_content_component.dart
- Changed test over comment field in template to be:
*ngIf="comment.isNotEmpty"
- Suites passed:
public/docs/_examples/lifecycle-hooks/dart
public/docs/_examples/lifecycle-hooks/ts
---
.../docs/_examples/lifecycle-hooks/dart/example-config.json | 0
.../lifecycle-hooks/dart/lib/after_content_component.dart | 2 +-
.../lifecycle-hooks/dart/lib/after_view_component.dart | 6 +++---
.../lifecycle-hooks/dart/lib/counter_component.dart | 6 +++---
.../_examples/lifecycle-hooks/dart/lib/spy_component.dart | 4 ++--
.../_examples/lifecycle-hooks/dart/lib/spy_directive.dart | 4 ++--
6 files changed, 11 insertions(+), 11 deletions(-)
create mode 100644 public/docs/_examples/lifecycle-hooks/dart/example-config.json
diff --git a/public/docs/_examples/lifecycle-hooks/dart/example-config.json b/public/docs/_examples/lifecycle-hooks/dart/example-config.json
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/after_content_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/after_content_component.dart
index 4e11dc702b..c43ea4de73 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/lib/after_content_component.dart
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/after_content_component.dart
@@ -20,7 +20,7 @@ class ChildComponent {
-- projected content begins --
-- projected content ends --
-
+
'''
// #enddocregion template
)
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart
index 308e36d9cd..c405c874ac 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart
@@ -22,16 +22,16 @@ class ChildViewComponent {
-- child view begins --
-- child view ends --
- ''',
+ ''',
// #enddocregion template
directives: const [ChildViewComponent])
// #docregion hooks
class AfterViewComponent implements AfterViewChecked, AfterViewInit {
var _prevHero = '';
-
+
// Query for a VIEW child of type `ChildViewComponent`
@ViewChild(ChildViewComponent) ChildViewComponent viewChild;
-
+
// #enddocregion hooks
final LoggerService _logger;
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/counter_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/counter_component.dart
index 65ae6d00f6..6434b9f8b5 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/lib/counter_component.dart
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/counter_component.dart
@@ -17,8 +17,8 @@ import 'spy_directive.dart';
styles: const [
'.counter {background: LightYellow; padding: 8px; margin-top: 8px}'
],
- directives: const [Spy])
-class MyCounter implements OnChanges {
+ directives: const [SpyDirective])
+class MyCounterComponent implements OnChanges {
@Input() num counter;
List changeLog = [];
@@ -53,7 +53,7 @@ class MyCounter implements OnChanges {
''',
styles: const ['.parent {background: gold;}'],
- directives: const [MyCounter],
+ directives: const [MyCounterComponent],
providers: const [LoggerService])
class CounterParentComponent {
final LoggerService _logger;
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.dart
index 815c8441d1..8006c39a14 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.dart
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.dart
@@ -11,7 +11,7 @@ import 'spy_directive.dart';
'.parent {background: khaki}',
'.heroes {background: LightYellow; padding: 0 8px}'
],
- directives: const [Spy],
+ directives: const [SpyDirective],
providers: const [LoggerService])
class SpyParentComponent {
final LoggerService _logger;
@@ -31,7 +31,7 @@ class SpyParentComponent {
}
// removeHero(String hero) { } is not used.
-
+
void reset() {
_logger.log('-- reset --');
heroes.clear();
diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_directive.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/spy_directive.dart
index 42db9f591a..c8656eceba 100644
--- a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_directive.dart
+++ b/public/docs/_examples/lifecycle-hooks/dart/lib/spy_directive.dart
@@ -9,10 +9,10 @@ int _nextId = 1;
// Spy on any element to which it is applied.
// Usage: ...
@Directive(selector: '[mySpy]')
-class Spy implements OnInit, OnDestroy {
+class SpyDirective implements OnInit, OnDestroy {
final LoggerService _logger;
- Spy(this._logger);
+ SpyDirective(this._logger);
ngOnInit() => _logIt('onInit');
From f8e6b5d1f74b86facb9357be6c4b76aa7da88363 Mon Sep 17 00:00:00 2001
From: Patrice Chalin
Date: Tue, 28 Jun 2016 13:15:29 -0700
Subject: [PATCH 18/31] docs(toh-5/dart): make dashboard more robust (#1688)
Originally the dashboard TS expression ``heroes.slice(1, 5))` had been
written as:
> _heroService.getHeroes().getRange(1, 5)
which is brittle; it fails if there are not enough heroes. Slice
doesn't fail; an equivalent express
ion in Dart is
> _heroService.getHeroes().skip(1).take(4)
This is now used.
Other changes:
- Fix in css (missed TS-side update).
- Ran `dartfmt` on `heroes_component.dart`.
---
.../toh-5/dart/lib/dashboard_component.dart | 2 +-
.../toh-5/dart/lib/dashboard_component_2.dart | 2 +-
public/docs/_examples/toh-5/dart/lib/hero.dart | 2 +-
.../toh-5/dart/lib/hero_detail_component.dart | 3 +--
.../toh-5/dart/lib/heroes_component.css | 2 +-
.../toh-5/dart/lib/heroes_component.dart | 17 ++++++++++-------
6 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart
index 972497e065..ff0fb8c0d1 100644
--- a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart
+++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart
@@ -32,7 +32,7 @@ class DashboardComponent implements OnInit {
// #enddocregion ctor
Future ngOnInit() async {
- heroes = (await _heroService.getHeroes()).getRange(1, 5).toList();
+ heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
}
// #docregion goto-detail
diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart
index 15d239ba1b..aa9afb38d7 100644
--- a/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart
+++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart
@@ -19,7 +19,7 @@ class DashboardComponent implements OnInit {
DashboardComponent(this._heroService);
Future ngOnInit() async {
- heroes = (await _heroService.getHeroes()).getRange(1, 5).toList();
+ heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
}
gotoDetail() {/* not implemented yet */}
diff --git a/public/docs/_examples/toh-5/dart/lib/hero.dart b/public/docs/_examples/toh-5/dart/lib/hero.dart
index d62b733142..828f8cebab 100644
--- a/public/docs/_examples/toh-5/dart/lib/hero.dart
+++ b/public/docs/_examples/toh-5/dart/lib/hero.dart
@@ -3,4 +3,4 @@ class Hero {
String name;
Hero(this.id, this.name);
-}
\ No newline at end of file
+}
diff --git a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart
index ed648d626f..a6c506a231 100644
--- a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart
+++ b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart
@@ -1,6 +1,5 @@
// #docplaster
-// #docregion
-// #docregion v2
+// #docregion , v2
import 'dart:async';
import 'dart:html';
diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.css b/public/docs/_examples/toh-5/dart/lib/heroes_component.css
index d939ab565d..35e45af98d 100644
--- a/public/docs/_examples/toh-5/dart/lib/heroes_component.css
+++ b/public/docs/_examples/toh-5/dart/lib/heroes_component.css
@@ -6,7 +6,7 @@
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
- width: 10em;
+ width: 15em;
}
.heroes li {
cursor: pointer;
diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.dart b/public/docs/_examples/toh-5/dart/lib/heroes_component.dart
index fda869c3aa..48e1a167bf 100644
--- a/public/docs/_examples/toh-5/dart/lib/heroes_component.dart
+++ b/public/docs/_examples/toh-5/dart/lib/heroes_component.dart
@@ -14,10 +14,9 @@ import 'hero_service.dart';
selector: 'my-heroes',
// #enddocregion heroes-component-renaming
templateUrl: 'heroes_component.html',
- styleUrls: const ['heroes_component.css'],
- directives: const [HeroDetailComponent]
- // #docregion heroes-component-renaming
-)
+ styleUrls: const ['heroes_component.css'],
+ directives: const [HeroDetailComponent])
+// #docregion heroes-component-renaming
// #enddocregion heroes-component-renaming, metadata
// #docregion class, heroes-component-renaming
class HeroesComponent implements OnInit {
@@ -37,9 +36,13 @@ class HeroesComponent implements OnInit {
getHeroes();
}
- void onSelect(Hero hero) { selectedHero = hero; }
+ void onSelect(Hero hero) {
+ selectedHero = hero;
+ }
- Future gotoDetail() =>
- _router.navigate(['HeroDetail', {'id': selectedHero.id.toString()}]);
+ Future gotoDetail() => _router.navigate([
+ 'HeroDetail',
+ {'id': selectedHero.id.toString()}
+ ]);
// #docregion heroes-component-renaming
}
From e5b11d456c31fa2e6879bdf5ba6ce3013d20e237 Mon Sep 17 00:00:00 2001
From: Patrice Chalin
Date: Tue, 28 Jun 2016 13:15:51 -0700
Subject: [PATCH 19/31] docs(guide/attribute-directives): follow-up to #1654
(#1765)
- Updated Dart code to match TS.
- Ran dartfmt.
- Enabled e2e tests; suites passed:
- public/docs/_examples/attribute-directives/dart
- public/docs/_examples/attribute-directives/ts
- Prose copyedits.
---
.../dart/example-config.json | 0
.../dart/lib/highlight_directive.dart | 30 ++++++++++---------
.../dart/lib/highlight_directive_2.dart | 27 ++++++++++-------
.../ts/app/highlight.directive.2.ts | 3 +-
.../ts/app/highlight.directive.ts | 8 ++---
.../ts/latest/guide/attribute-directives.jade | 24 +++++++--------
6 files changed, 49 insertions(+), 43 deletions(-)
create mode 100644 public/docs/_examples/attribute-directives/dart/example-config.json
diff --git a/public/docs/_examples/attribute-directives/dart/example-config.json b/public/docs/_examples/attribute-directives/dart/example-config.json
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive.dart b/public/docs/_examples/attribute-directives/dart/lib/highlight_directive.dart
index e6190a443c..d0a2dc8726 100644
--- a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive.dart
+++ b/public/docs/_examples/attribute-directives/dart/lib/highlight_directive.dart
@@ -2,39 +2,41 @@
// #docregion full
import 'package:angular2/core.dart';
-@Directive(selector: '[myHighlight]', host: const {
- '(mouseenter)': 'onMouseEnter()',
- '(mouseleave)': 'onMouseLeave()'
-})
-// #docregion class-1
+@Directive(selector: '[myHighlight]')
+// #docregion class
class HighlightDirective {
String _defaultColor = 'red';
final dynamic _el;
HighlightDirective(ElementRef elRef) : _el = elRef.nativeElement;
- // #enddocregion class-1
+ // #enddocregion class
// #docregion defaultColor
- @Input() set defaultColor(String colorName) {
+ @Input()
+ set defaultColor(String colorName) {
_defaultColor = (colorName ?? _defaultColor);
}
// #enddocregion defaultColor
- // #docregion class-1
+ // #docregion class
// #docregion color
- @Input('myHighlight') String highlightColor;
+ @Input('myHighlight')
+ String highlightColor;
// #enddocregion color
-
+
// #docregion mouse-enter
- void onMouseEnter() { _highlight(highlightColor ?? _defaultColor); }
+ @HostListener('mouseenter')
+ void onMouseEnter() => _highlight(highlightColor ?? _defaultColor);
+
// #enddocregion mouse-enter
- void onMouseLeave() { _highlight(); }
+ @HostListener('mouseleave')
+ void onMouseLeave() => _highlight();
void _highlight([String color]) {
- if(_el != null) _el.style.backgroundColor = color;
+ if (_el != null) _el.style.backgroundColor = color;
}
}
-// #enddocregion class-1
+// #enddocregion class
// #enddocregion full
/*
// #docregion highlight
diff --git a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_2.dart b/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_2.dart
index 8546f36279..6745685c09 100644
--- a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_2.dart
+++ b/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_2.dart
@@ -1,14 +1,7 @@
// #docregion
import 'package:angular2/core.dart';
-@Directive(selector: '[myHighlight]',
- // #docregion host
- host: const {
- '(mouseenter)': 'onMouseEnter()',
- '(mouseleave)': 'onMouseLeave()'
- }
- // #enddocregion host
-)
+@Directive(selector: '[myHighlight]')
class HighlightDirective {
// #docregion ctor
final dynamic _el;
@@ -16,9 +9,21 @@ class HighlightDirective {
HighlightDirective(ElementRef elRef) : _el = elRef.nativeElement;
// #enddocregion ctor
- // #docregion mouse-methods
- void onMouseEnter() { _highlight("yellow"); }
- void onMouseLeave() { _highlight(); }
+ // #docregion mouse-methods, host
+ @HostListener('mouseenter')
+ void onMouseEnter() {
+ // #enddocregion host
+ _highlight('yellow');
+ // #docregion host
+ }
+
+ @HostListener('mouseleave')
+ void onMouseLeave() {
+ // #enddocregion host
+ _highlight();
+ // #docregion host
+ }
+ // #enddocregion host
void _highlight([String color]) {
if (_el != null) _el.style.backgroundColor = color;
diff --git a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts
index 3baf3449fb..8dec85912e 100644
--- a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts
+++ b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts
@@ -1,5 +1,4 @@
/* tslint:disable:no-unused-variable */
-// #docplaster
// #docregion
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@@ -8,9 +7,9 @@ import { Directive, ElementRef, HostListener, Input } from '@angular/core';
})
export class HighlightDirective {
-
// #docregion ctor
private el: HTMLElement;
+
constructor(el: ElementRef) { this.el = el.nativeElement; }
// #enddocregion ctor
diff --git a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts
index cd6c7870a1..2ebcd3a995 100644
--- a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts
+++ b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts
@@ -5,20 +5,20 @@ import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[myHighlight]'
})
-// #docregion class-1
+// #docregion class
export class HighlightDirective {
private _defaultColor = 'red';
private el: HTMLElement;
constructor(el: ElementRef) { this.el = el.nativeElement; }
- // #enddocregion class-1
+ // #enddocregion class
// #docregion defaultColor
@Input() set defaultColor(colorName: string){
this._defaultColor = colorName || this._defaultColor;
}
// #enddocregion defaultColor
- // #docregion class-1
+ // #docregion class
// #docregion color
@Input('myHighlight') highlightColor: string;
@@ -37,7 +37,7 @@ export class HighlightDirective {
this.el.style.backgroundColor = color;
}
}
-// #enddocregion class-1
+// #enddocregion class
// #enddocregion full
/*
// #docregion highlight
diff --git a/public/docs/ts/latest/guide/attribute-directives.jade b/public/docs/ts/latest/guide/attribute-directives.jade
index 9232b2c5f2..e6db286405 100644
--- a/public/docs/ts/latest/guide/attribute-directives.jade
+++ b/public/docs/ts/latest/guide/attribute-directives.jade
@@ -64,7 +64,7 @@ a#write-directive
include ../_quickstart_repo
:marked
Create the following source file in the indicated folder with the given code:
-+makeExample('attribute-directives/ts/app/highlight.directive.1.ts', null, 'app/highlight.directive.ts')
++makeExample('app/highlight.directive.1.ts')
block highlight-directive-1
:marked
@@ -97,7 +97,7 @@ block highlight-directive-1
We need a prefix of our own, preferably short, and `my` will do for now.
p
- | After the `@Directive` metadata comes the directive's controller class, which contains the logic for the directive.
+ | After the #[code @Directive] metadata comes the directive's controller class, which contains the logic for the directive.
+ifDocsFor('ts')
| We export `HighlightDirective` to make it accessible to other components.
:marked
@@ -169,13 +169,13 @@ a#respond-to-user
1. detect when the user hovers into and out of the element,
2. respond to those actions by setting and clearing the highlight color, respectively.
- We use the `@HostListener` decorator on a method which is called when the event is raised.
+ We apply the `@HostListener` !{_decorator} to methods which are called when an event is raised.
+makeExample('attribute-directives/ts/app/highlight.directive.2.ts','host')(format=".")
.l-sub-section
:marked
- The `@HostListener` decorator refers to the DOM element that hosts our attribute directive, the `` in our case.
+ The `@HostListener` !{_decorator} refers to the DOM element that hosts our attribute directive, the `
` in our case.
We could have attached event listeners by manipulating the host DOM element directly, but
there are at least three problems with such an approach:
@@ -184,7 +184,7 @@ a#respond-to-user
1. We must *detach* our listener when the directive is destroyed to avoid memory leaks.
1. We'd be talking to DOM API directly which, we learned, is something to avoid.
- Let's roll with the `@HostListener` decorator.
+ Let's roll with the `@HostListener` !{_decorator}.
:marked
Now we implement the two mouse event handlers:
+makeExample('attribute-directives/ts/app/highlight.directive.2.ts','mouse-methods')(format=".")
@@ -195,7 +195,7 @@ a#respond-to-user
+makeExample('attribute-directives/ts/app/highlight.directive.2.ts','ctor')(format=".")
:marked
Here's the updated directive:
-+makeExample('attribute-directives/ts/app/highlight.directive.2.ts',null, 'app/highlight.directive.ts')
++makeExample('app/highlight.directive.2.ts')
:marked
We run the app and confirm that the background color appears as we move the mouse over the `p` and
disappears as we move out.
@@ -213,12 +213,12 @@ a#bindings
We'll extend our directive class with a bindable **input** `highlightColor` property and use it when we highlight text.
Here is the final version of the class:
-+makeExample('attribute-directives/ts/app/highlight.directive.ts', 'class-1', 'app/highlight.directive.ts (class only)')
++makeExcerpt('app/highlight.directive.ts', 'class')
a#input
:marked
The new `highlightColor` property is called an *input* property because data flows from the binding expression into our directive.
Notice the `@Input()` #{_decorator} applied to the property.
-+makeExample('attribute-directives/ts/app/highlight.directive.ts', 'color')
++makeExcerpt('app/highlight.directive.ts', 'color')
:marked
`@Input` adds metadata to the class that makes the `highlightColor` property available for
property binding under the `myHighlight` alias.
@@ -232,25 +232,25 @@ a#input
We could resolve the discrepancy by renaming the property to `myHighlight` and define it as follows:
- +makeExample('attribute-directives/ts/app/highlight.directive.ts', 'highlight')
+ +makeExcerpt('app/highlight.directive.ts', 'highlight', '')
:marked
Maybe we don't want that property name inside the directive perhaps because it
doesn't express our intention well.
We can **alias** the `highlightColor` property with the attribute name by
passing `myHighlight` into the `@Input` #{_decorator}:
- +makeExample('attribute-directives/ts/app/highlight.directive.ts', 'color')
+ +makeExcerpt('app/highlight.directive.ts', 'color', '')
:marked
Now that we're getting the highlight color as an input, we modify the `onMouseEnter()` method to use
it instead of the hard-coded color name.
We also define red as the default color to fallback on in case
the user neglects to bind with a color.
-+makeExample('attribute-directives/ts/app/highlight.directive.ts', 'mouse-enter')
++makeExcerpt('attribute-directives/ts/app/highlight.directive.ts', 'mouse-enter', '')
:marked
Now we'll update our `AppComponent` template to let
users pick the highlight color and bind their choice to our directive.
Here is the updated template:
-+makeExample('attribute-directives/ts/app/app.component.html', 'v2')
++makeExcerpt('attribute-directives/ts/app/app.component.html', 'v2', '')
.l-sub-section
:marked
From 8548d3cb06b95dc29a04fde6015f991c1b70c054 Mon Sep 17 00:00:00 2001
From: Naomi Black
Date: Tue, 28 Jun 2016 13:57:46 -0700
Subject: [PATCH 20/31] chore(nav): update left nav to add glossary back
---
public/docs/dart/latest/guide/_data.json | 6 ++++++
public/docs/js/latest/guide/_data.json | 6 ++++++
public/docs/ts/latest/guide/_data.json | 6 ++++++
3 files changed, 18 insertions(+)
diff --git a/public/docs/dart/latest/guide/_data.json b/public/docs/dart/latest/guide/_data.json
index 7d25438019..eff9a7e77e 100644
--- a/public/docs/dart/latest/guide/_data.json
+++ b/public/docs/dart/latest/guide/_data.json
@@ -73,6 +73,12 @@
"intro": "Learn how to apply CSS styles to components."
},
+ "glossary": {
+ "title": "Glossary",
+ "intro": "Brief definitions of the most important words in the Angular 2 vocabulary",
+ "basics": true
+ },
+
"security": {
"title": "Security",
"intro": "Prevent security vulnerabilities"
diff --git a/public/docs/js/latest/guide/_data.json b/public/docs/js/latest/guide/_data.json
index 567324b649..1e0d9aa221 100644
--- a/public/docs/js/latest/guide/_data.json
+++ b/public/docs/js/latest/guide/_data.json
@@ -73,6 +73,12 @@
"intro": "Learn how to apply CSS styles to components."
},
+ "glossary": {
+ "title": "Glossary",
+ "intro": "Brief definitions of the most important words in the Angular 2 vocabulary",
+ "basics": true
+ },
+
"hierarchical-dependency-injection": {
"title": "Hierarchical Dependency Injectors",
"navTitle": "Hierarchical Injectors",
diff --git a/public/docs/ts/latest/guide/_data.json b/public/docs/ts/latest/guide/_data.json
index 8b19ebe7e8..3bc69e1c15 100644
--- a/public/docs/ts/latest/guide/_data.json
+++ b/public/docs/ts/latest/guide/_data.json
@@ -86,6 +86,12 @@
"intro": "Learn how to apply CSS styles to components."
},
+ "glossary": {
+ "title": "Glossary",
+ "intro": "Brief definitions of the most important words in the Angular 2 vocabulary",
+ "basics": true
+ },
+
"hierarchical-dependency-injection": {
"title": "Hierarchical Dependency Injectors",
"navTitle": "Hierarchical Injectors",
From 28b531672744d72e5b650a3f76c07423f732bb09 Mon Sep 17 00:00:00 2001
From: Naomi Black
Date: Tue, 28 Jun 2016 16:08:38 -0700
Subject: [PATCH 21/31] docs(forms): add more to the top of doc warning about
bootstrap
---
public/docs/ts/latest/guide/forms.jade | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/public/docs/ts/latest/guide/forms.jade b/public/docs/ts/latest/guide/forms.jade
index b17f979a71..65cd6f097c 100644
--- a/public/docs/ts/latest/guide/forms.jade
+++ b/public/docs/ts/latest/guide/forms.jade
@@ -2,9 +2,11 @@ include ../_util-fns
.alert.is-important
:marked
- This guide is using the new forms API.
+ This guide is using the new forms API. To use this API, you must opt in by adding special
+ providers to your bootstrap file (see the Bootstrap seection below).
- The old forms API is deprecated, but we still maintain a separate version of the guide using the deprecated forms API here .
+ The old forms API is deprecated, but we still maintain a separate version of the guide using
+ the deprecated forms API here .
:marked
We’ve all used a form to login, submit a help request, place an order, book a flight,
From 8d7e7a01878d1f8761539948421431fd61b5b51b Mon Sep 17 00:00:00 2001
From: Fabriece Sumuni
Date: Fri, 17 Jun 2016 23:51:53 +0200
Subject: [PATCH 22/31] fixed a formatting typo on line 1015
---
public/docs/ts/latest/guide/router.jade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/docs/ts/latest/guide/router.jade b/public/docs/ts/latest/guide/router.jade
index 817912f031..6c33f329f0 100644
--- a/public/docs/ts/latest/guide/router.jade
+++ b/public/docs/ts/latest/guide/router.jade
@@ -1024,7 +1024,7 @@ h2#guards Route Guards
These are all asynchronous operations.
Accordingly, a routing guard can return an `Observable` and the
- router will wait for the observable to resolve to `true` or `false.
+ router will wait for the observable to resolve to `true` or `false`.
The router supports two kinds of guards:
From 7fa73c4cb01888c36b65cecb4a5216459b05538f Mon Sep 17 00:00:00 2001
From: Naomi Black
Date: Tue, 28 Jun 2016 16:49:12 -0700
Subject: [PATCH 23/31] chore(june28): updates to news, events, team bio for
max
---
harp.json | 17 ++++++++++++-
public/events.jade | 23 ++++++++---------
public/news.jade | 28 ++++++++++-----------
public/resources/images/bios/max-sills.jpg | Bin 0 -> 11772 bytes
4 files changed, 41 insertions(+), 27 deletions(-)
create mode 100644 public/resources/images/bios/max-sills.jpg
diff --git a/harp.json b/harp.json
index 0d9b1cb9f8..8c593c48d6 100644
--- a/harp.json
+++ b/harp.json
@@ -75,6 +75,7 @@
"name": "Victor Savkin",
"picture": "/resources/images/bios/victor.jpg",
"twitter": "victorsavkin",
+ "website": "http://victorsavkin.com/",
"bio": "Victor works on Angular at Google. He is interested in functional programming and client-side applications. Being a language nerd he spends a lot of his time playing with TypeScript, Dart, Elm, Haskell, and Clojure.",
"type": "Google"
},
@@ -101,6 +102,7 @@
"name": "David East",
"picture": "/resources/images/bios/david-east.jpg",
"twitter": "_davideast",
+ "website":"https://github.com/davideast",
"bio": "David East is a Developer Programs Engineer at Google. He works full-time on the Firebase team and part-time on the Angular core team.",
"type": "Google"
},
@@ -217,6 +219,7 @@
"name": "Lucas Mirelmann",
"picture": "/resources/images/bios/lucas.jpg",
"twitter": "lgalfaso",
+ "website": "https://github.com/lgalfaso",
"bio": "Lucas works as a Software Engineer at Google and is a core Angular contributor.",
"type": "Google"
},
@@ -243,6 +246,7 @@
"name": "Robert Messerle",
"picture": "/resources/images/bios/rmesserle.jpg",
"twitter": "Bobbo_O",
+ "website": "https://github.com/robertmesserle",
"bio": "Robert is a software engineer on the Angular team at Google, working primarily on the Angular Material project.",
"type": "Google"
},
@@ -258,6 +262,8 @@
"scott": {
"name": "Scott Hyndman",
"picture": "/resources/images/bios/scott.jpg",
+ "twitter": "scotthyndman",
+ "website": "https://github.com/shyndman",
"bio": "Scott works for Google on the Material Design team, where he brings designers' dreams to life on the web.",
"type": "Google"
},
@@ -266,6 +272,7 @@
"name": "Kara Erickson",
"picture": "/resources/images/bios/kara-erickson.jpg",
"twitter": "karaforthewin",
+ "website": "https://github.com/kara",
"bio": "Kara is a software engineer on the Angular team at Google and a co-organizer of the Angular-SF Meetup. Prior to Google, she helped build UI components in Angular for guest management systems at OpenTable. She enjoys snacking indiscriminately and probably other things too.",
"type": "Google"
},
@@ -294,6 +301,14 @@
"bio": "Rob is a Developer Advocate on the Angular team at Google. He's the Angular team's resident reactive programming geek and founded the Reactive Extensions for Angular project, ngrx.",
"type": "Google"
},
+ "maxsills": {
+ "name": "Max Sills",
+ "picture": "/resources/images/bios/max-sills.jpg",
+ "twitter": "angularjs",
+ "website": "http://google-opensource.blogspot.com/",
+ "bio": "Max Sills is Angular's Open Source lawyer.",
+ "type": "Google"
+ },
"pawel": {
"name": "Pawel Kozlowski",
@@ -322,7 +337,7 @@
"elad": {
"name": "Elad Bezalel",
"picture": "/resources/images/bios/eladbezalel.jpg",
- "website": "https://github.com/EladBezalel",
+ "website": "https://github.com/EladBezalel",
"bio": "Elad is a fullstack developer with a very strong love for design. Since 8 years old, he's been designing in Photoshop and later on fell in love with programing. This strong bond between design and computer programming gave birth to a new kind of love. And he is currently doing the combination of both, as a core member of the ngMaterial project.",
"type": "Community"
},
diff --git a/public/events.jade b/public/events.jade
index 36d0634e2a..2c0acabad0 100644
--- a/public/events.jade
+++ b/public/events.jade
@@ -7,17 +7,6 @@ table.is-full-width
tbody
-
- tr
- th
- a(
- target="_blank"
- href="http://devoxx.pl/"
- ) Devoxx
- td Krakow, Poland
- td June 22-25, 2016
-
-
tr
th
@@ -91,4 +80,14 @@ table.is-full-width
href="http://www.dotjs.io/"
) dotJS
td Paris, France
- td Dec. 5, 2016
\ No newline at end of file
+ td Dec. 5, 2016
+
+
+ tr
+ th
+ a(
+ target="_blank"
+ href="https://ng-be.org/"
+ ) NG-BE
+ td Ghent, Belgium
+ td Dec. 9, 2016
diff --git a/public/news.jade b/public/news.jade
index 7590943b31..10f54d87c8 100644
--- a/public/news.jade
+++ b/public/news.jade
@@ -4,6 +4,20 @@
.clear
.grid-fluid
+ .c6
+ .article-card
+ .date June 21, 2016
+ .title
+ a(
+ target="_blank"
+ href="http://angularjs.blogspot.com/2016/06/rc3-now-available.html"
+ ) RC3 Now Available
+ p oday we’re happy to announce that we are shipping Angular 2.0.0-rc3. This release includes a fix for a major performance regression in RC2...
+
+ .author
+ img(src="/resources/images/bios/stephenfluin.jpg")
+ .posted Posted by Stephen Fluin
+
.c6
.article-card
.date June 15, 2016
@@ -17,20 +31,6 @@
img(src="/resources/images/bios/stephenfluin.jpg")
.posted Posted by Stephen Fluin
- .c6
- .article-card
- .date June 9, 2016
- .title
- a(
- target="_blank"
- href="http://angularjs.blogspot.com/2016/06/improvements-coming-for-routing-in.html"
- ) Improvements Coming for Routing in Angular
- p A little more than a month ago, we introduced a new router at ng-conf. We’re grateful to have heard from many folks at ng-conf about flaws in this new design, so we are announcing...
-
- .author
- img(src="/resources/images/bios/stephenfluin.jpg")
- .posted Posted by Stephen Fluin
-
.grid-fluid.l-space-bottom-2.l-space-top-4
.c12.text-center
h3.text-headline.text-uppercase Developer Community
diff --git a/public/resources/images/bios/max-sills.jpg b/public/resources/images/bios/max-sills.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7826e8579f56e87f19500c36bbf21934442615c0
GIT binary patch
literal 11772
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
literal 0
HcmV?d00001
From f1f03cf28cd73fe65983d0b180724418ad2a3618 Mon Sep 17 00:00:00 2001
From: Mike Ryan
Date: Thu, 23 Jun 2016 07:11:06 -0500
Subject: [PATCH 24/31] chore(bios): Add Mike Ryan
---
harp.json | 8 ++++++++
public/resources/images/bios/mikeryan.jpg | Bin 0 -> 39766 bytes
2 files changed, 8 insertions(+)
create mode 100755 public/resources/images/bios/mikeryan.jpg
diff --git a/harp.json b/harp.json
index 8c593c48d6..a9b21e2b99 100644
--- a/harp.json
+++ b/harp.json
@@ -462,6 +462,14 @@
"website": "http://eric.to/",
"bio": "Eric is a gamer, writer, and programmer.",
"type": "Community"
+ },
+ "mikeryan": {
+ "name": "Mike Ryan",
+ "picture": "/resources/images/bios/mikeryan.jpg",
+ "twitter": "mikeryan52",
+ "website": "https://medium.com/@MikeRyan52",
+ "bio": "Mike Ryan is a Software Engineer at Synapse Wireless, working on solving challenging problems in the internet-of-things space. He is an advocate of reactive programming and a core contributor to the ngrx project.",
+ "type": "Community"
}
}
}
diff --git a/public/resources/images/bios/mikeryan.jpg b/public/resources/images/bios/mikeryan.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..da05b1d170011673cd775d8734dcb91938176d42
GIT binary patch
literal 39766
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 I{p(P+s+LYFR*#(RxbJ|4k_JM
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