Merge remote-tracking branch 'remotes/angular.io/master'

# Conflicts:
#	public/docs/ts/latest/cookbook/dependency-injection.jade
#	public/docs/ts/latest/glossary.jade
#	public/docs/ts/latest/guide/forms.jade
#	public/docs/ts/latest/guide/hierarchical-dependency-injection.jade
#	public/docs/ts/latest/guide/lifecycle-hooks.jade
#	public/docs/ts/latest/guide/server-communication.jade
#	public/docs/ts/latest/guide/template-syntax.jade
#	public/docs/ts/latest/guide/user-input.jade
#	public/docs/ts/latest/guide/webpack.jade
#	public/docs/ts/latest/quickstart.jade
#	public/docs/ts/latest/tutorial/toh-pt2.jade
#	public/docs/ts/latest/tutorial/toh-pt4.jade
#	public/docs/ts/latest/tutorial/toh-pt5.jade
#	public/docs/ts/latest/tutorial/toh-pt6.jade
This commit is contained in:
Zhimin YE (Rex) 2016-08-23 14:02:54 +01:00
commit 654030f09d
178 changed files with 4266 additions and 2961 deletions

View File

@ -10,7 +10,7 @@ env:
- DBUS_SESSION_BUS_ADDRESS=/dev/null
- DISPLAY=:99.0
- CHROME_BIN=chromium-browser
- LATEST_RELEASE=2.0.0-rc.4
- LATEST_RELEASE=2.0.0-rc.5
- TASK_FLAGS="--dgeni-log=warn"
# - TASK_FLAGS=""
matrix:

View File

@ -344,10 +344,14 @@ function runE2eDartTests(appDir, outputFile) {
gutil.log('http-server failed to launch over ' + deployDir);
return false;
}
var pubUpgradeSpawnInfo = spawnExt('pub', ['upgrade'], { cwd: appDir });
var prepPromise = pubUpgradeSpawnInfo.promise.then(function (data) {
return spawnExt('pub', ['build'], { cwd: appDir }).promise;
});
if (argv.pub === false) {
var prepPromise = Promise.resolve(true);
} else {
var pubUpgradeSpawnInfo = spawnExt('pub', ['upgrade'], { cwd: appDir });
var prepPromise = pubUpgradeSpawnInfo.promise.then(function (data) {
return spawnExt('pub', ['build'], { cwd: appDir }).promise;
});
}
return runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile);
}
@ -441,7 +445,7 @@ gulp.task('add-example-boilerplate', function(done) {
// copies boilerplate files to locations
// where an example app is found
gulp.task('_copy-example-boilerplate', function (done) {
if (!argv.fast) buildStyles(copyExampleBoilerplate, done);
return argv.fast ? done() : buildStyles(copyExampleBoilerplate, done);
});
//Builds Angular 2 Docs CSS file from Bootstrap npm LESS source
@ -604,20 +608,20 @@ gulp.task('build-dart-cheatsheet', [], function() {
gulp.task('dartdoc', ['pub upgrade'], function() {
const ngRepoPath = ngPathFor('dart');
if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'doc'))) {
gutil.log('Skipping dartdoc: --fast flag enabled and "doc" dir exists');
if (argv.fast && fs.existsSync(path.resolve(ngRepoPath, 'docs', 'api'))) {
gutil.log('Skipping dartdoc: --fast flag enabled and "docs/api" dir exists');
return true;
}
checkAngularProjectPath(ngRepoPath);
const topLevelLibFilePath = path.resolve(ngRepoPath, 'lib', 'angular2.dart');
const tmpPath = topLevelLibFilePath + '.disabled';
if (!fs.existsSync(topLevelLibFilePath)) throw new Error(`Missing file: ${topLevelLibFilePath}`);
fs.renameSync(topLevelLibFilePath, tmpPath);
renameIfExistsSync(topLevelLibFilePath, tmpPath);
gutil.log(`Hiding top-level angular2 library: ${topLevelLibFilePath}`);
const dartdoc = spawnExt('dartdoc', ['--output', 'doc/api', '--add-crossdart'], { cwd: ngRepoPath});
// Remove dartdoc '--add-crossdart' flag while we are fixing links to API pages.
const dartdoc = spawnExt('dartdoc', ['--output', 'docs/api'], { cwd: ngRepoPath});
return dartdoc.promise.finally(() => {
gutil.log(`Restoring top-level angular2 library: ${topLevelLibFilePath}`);
fs.renameSync(tmpPath, topLevelLibFilePath);
renameIfExistsSync(tmpPath, topLevelLibFilePath);
})
});
@ -1235,15 +1239,14 @@ function buildDartCheatsheet() {
function buildApiDocsForDart() {
const apiDir = 'api';
const vers = 'latest';
const dab = require('./tools/dart-api-builder/dab')(ANGULAR_IO_PROJECT_PATH);
const log = dab.log;
log.level = _dgeniLogLevel;
const dabInfo = dab.dartPkgConfigInfo;
dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, apiDir);
dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), 'doc', apiDir);
dabInfo.ngIoDartApiDocPath = path.join(DOCS_PATH, 'dart', vers, 'api');
dabInfo.ngDartDocPath = path.join(ngPathFor('dart'), 'docs', 'api');
// Exclude API entries for developer/internal libraries. Also exclude entries for
// the top-level catch all "angular2" library (otherwise every entry appears twice).
dabInfo.excludeLibRegExp = new RegExp(/^(?!angular2)|\.testing|_|codegen|^angular2$/);
@ -1455,3 +1458,11 @@ function checkAngularProjectPath(_ngPath) {
if (fs.existsSync(ngPath)) return;
throw new Error('API related tasks require the angular2 repo to be at ' + ngPath);
}
function renameIfExistsSync(oldPath, newPath) {
if (fs.existsSync(oldPath)) {
fs.renameSync(oldPath, newPath);
} else {
gutil.log(`renameIfExistsSync cannot find file to rename: ${oldPath}`);
}
}

View File

@ -39,6 +39,15 @@
//- Location of sample code
- var _liveLink = 'live link';
//- NgModule related
- var _AppModuleVsAppComp = 'AppModule'
- var _appModuleTsVsAppCompTs = 'app/app.module.ts'
- var _appModuleTsVsMainTs = 'app/app.module.ts'
- var _bootstrapModule = 'bootstrapModule'
- var _moduleVsComp = 'module'
- var _moduleVsRootComp = 'module'
- var _platformBrowserDynamicVsBootStrap = 'platformBrowserDynamic'
//- Other
- var _truthy = 'truthy';
- var _falsey = 'falsey';
@ -90,14 +99,14 @@ mixin makeExample(_filePath, region, _title, stylePatterns)
//- ending is given or is just (), then the title will be suffixed with
//- either "(excerpt)", or "(#{_region})" when _region is defined.
mixin makeExcerpt(_filePath, _region, _title, stylePatterns)
- var matches = _filePath.match(/(.*)\s+\(([\w ]*)\)$/);
- var matches = _filePath.match(/(.*)\s+\(([^\)]*)\)$/);
- var parenText;
- if (matches) { _filePath = matches[1]; parenText = matches[2]; }
- var adjustments = adjustExamplePathAndTitle({filePath:_filePath, title:_title});
- var filePath = adjustments.filePath;
- var title = adjustments.title;
- var region = _region || parenText;
- var excerpt = !region || parenText === '' ? 'excerpt' : parenText || region;
- var region = _region || (_region === '' ? '' : parenText);
- var excerpt = parenText || region || 'excerpt';
- if (title) title = title + ' (' + excerpt + ')';
+makeExample(filePath, region, title, stylePatterns)(format='.')
@ -214,8 +223,8 @@ script.
- // E.g. of a project relative path is 'app/main.ts'
- if (ex.title === null || ex.title === undefined) {
- // Title is not given so take it to be ex.filePath.
- // Is title like styles.1.css? Then drop the '.1' qualifier:
- var matches = ex.filePath.match(/^(.*)\.\d(\.\w+)$/);
- // Title like styles.1.css or foo_1.dart? Then drop the '.1' or '_1' qualifier:
- var matches = ex.filePath.match(/^(.*)[\._]\d(\.\w+)$/);
- ex.title = matches ? matches[1] + matches[2] : ex.filePath;
- }
- ex.filePath = getExampleName() + '/' + _docsFor + '/' + ex.filePath;

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -2,17 +2,16 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { MovieListComponent } from './movie-list.component';
import { routes } from './app.routes';
import { routing } from './app.routing';
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes, {})
routing
],
declarations: [
AppComponent,

View File

@ -1,9 +0,0 @@
// #docregion
import { RouterConfig } from '@angular/router';
import { MovieListComponent } from './movie-list.component';
export const routes: RouterConfig = [
{ path: '', redirectTo: '/movies', pathMatch: 'full' },
{ path: 'movies', component: MovieListComponent }
];

View File

@ -0,0 +1,12 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MovieListComponent } from './movie-list.component';
const routes: Routes = [
{ path: '', redirectTo: '/movies', pathMatch: 'full' },
{ path: 'movies', component: MovieListComponent }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);

View File

@ -1,15 +1,16 @@
// #docregion
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { XHRBackend } from '@angular/http';
// import { appRouterProviders } from './app.routes';
import { HttpModule } from '@angular/http';
/* import { routing } from './app.routing';*/
import { LocationStrategy,
HashLocationStrategy } from '@angular/common';
import { NgModule } from '@angular/core';
import { HeroData } from './hero-data';
import { InMemoryBackendService,
SEED_DATA } from 'angular2-in-memory-web-api';
import { InMemoryWebApiModule } from 'angular2-in-memory-web-api';
import { AppComponent } from './app.component';
import { HeroBioComponent } from './hero-bio.component';
@ -31,44 +32,43 @@ import { ParentFinderComponent,
BethComponent,
BobComponent } from './parent-finder.component';
const DIRECTIVES = [
const declarations = [
AppComponent,
HeroBiosComponent, HeroBiosAndContactsComponent, HeroBioComponent,
HeroesBaseComponent, SortedHeroesComponent,
HeroOfTheMonthComponent, HeroContactComponent,
HighlightDirective,
ParentFinderComponent,
AppComponent
];
const B_DIRECTIVES = [ BarryComponent, BethComponent, BobComponent ];
const a_components = [AliceComponent, AlexComponent ];
// #docregion C_DIRECTIVES
const C_DIRECTIVES = [
const b_components = [ BarryComponent, BethComponent, BobComponent ];
const c_components = [
CarolComponent, ChrisComponent, CraigComponent,
CathyComponent
];
// #enddocregion C_DIRECTIVES
// #docregion bootstrap
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ ...DIRECTIVES,
...B_DIRECTIVES,
...C_DIRECTIVES,
AliceComponent,
AlexComponent ],
imports: [
BrowserModule,
FormsModule,
HttpModule,
InMemoryWebApiModule.forRoot(HeroData)
// routing TODO: add routes
],
declarations: [
declarations,
a_components,
b_components,
c_components,
],
bootstrap: [ AppComponent ],
// #docregion providers
providers: [
// appRouterProviders, TODO: add routes
{ provide: LocationStrategy, useClass: HashLocationStrategy },
{ provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
{ provide: SEED_DATA, useClass: HeroData } // in-mem server data
{ provide: LocationStrategy, useClass: HashLocationStrategy }
]
// #enddocregion providers
})
export class AppModule {
constructor() {
}
}
// #enddocregion bootstraps
export class AppModule { }

View File

@ -1,7 +0,0 @@
import { provideRouter, RouterConfig } from '@angular/router';
const routes: RouterConfig = [];
export const appRouterProviders = [
provideRouter(routes)
];

View File

@ -0,0 +1,10 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
export const appRoutingProviders: any[] = [
];

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -7,7 +7,7 @@ import 'logger_service.dart';
//////////////////
// #docregion child-view
@Component(
selector: 'my-child',
selector: 'my-child-view',
template: '<input [(ngModel)]="hero">')
class ChildViewComponent {
String hero = 'Magneta';
@ -20,7 +20,7 @@ class ChildViewComponent {
// #docregion template
template: '''
<div>-- child view begins --</div>
<my-child></my-child>
<my-child-view></my-child-view>
<div>-- child view ends --</div>
<p *ngIf="comment.isNotEmpty" class="comment">{{comment}}</p>''',
// #enddocregion template

View File

@ -92,7 +92,7 @@ class DoCheckComponent implements DoCheck, OnChanges {
@Component(
selector: 'do-check-parent',
templateUrl: 'on_changes_parent_component.html',
templateUrl: 'do_check_parent_component.html',
styles: const ['.parent {background: Lavender}'],
directives: const [DoCheckComponent])
class DoCheckParentComponent {

View File

@ -0,0 +1,13 @@
<div class="parent">
<h2>{{title}}</h2>
<table>
<tr><td>Power: </td><td><input [(ngModel)]="power"></td></tr>
<tr><td>Hero.name: </td><td><input [(ngModel)]="hero.name"></td></tr>
</table>
<p><button (click)="reset()">Reset Log</button></p>
<!-- #docregion do-check -->
<do-check [hero]="hero" [power]="power"></do-check>
<!-- #enddocregion do-check -->
</div>

View File

@ -7,8 +7,7 @@
</table>
<p><button (click)="reset()">Reset Log</button></p>
<!-- #docregion on-changes -->
<!-- #docregion on-changes -->
<on-changes [hero]="hero" [power]="power"></on-changes>
<!-- #enddocregion on-changes -->
<do-check [hero]="hero" [power]="power"></do-check>
<!-- #enddocregion on-changes -->
</div>

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -1,8 +1,6 @@
// #docregion
import 'package:angular2/platform/browser.dart';
import 'package:lifecycle_hooks/app_component.dart';
main() {
void main() {
bootstrap(AppComponent);
}

View File

@ -1,4 +1,3 @@
// #docregion
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

View File

@ -7,7 +7,7 @@
</table>
<p><button (click)="reset()">Reset Log</button></p>
<!-- #docregion on-changes -->
<!-- #docregion on-changes -->
<on-changes [hero]="hero" [power]="power"></on-changes>
<!-- #enddocregion on-changes -->
<!-- #enddocregion on-changes -->
</div>

View File

@ -1,3 +1,4 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes,
RouterModule } from '@angular/router';
@ -7,4 +8,4 @@ export const routes: Routes = [
{ path: 'heroes', loadChildren: 'app/hero/hero.module.3' }
];
export const routing = RouterModule.forRoot(routes);
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);

View File

@ -1,4 +1,5 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes,
RouterModule } from '@angular/router';
@ -11,5 +12,5 @@ export const routes: Routes = [
];
// #docregion forRoot
export const routing = RouterModule.forRoot(routes);
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
// #enddocregion forRoot

View File

@ -1,7 +1,8 @@
import { ModuleWithProviders } from '@angular/core';
import { RouterModule } from '@angular/router';
import { ContactComponent } from './contact.component.3';
export const routing = RouterModule.forChild([
export const routing: ModuleWithProviders = RouterModule.forChild([
{ path: 'contact', component: ContactComponent}
]);

View File

@ -1,9 +1,10 @@
import { ModuleWithProviders } from '@angular/core';
import { RouterModule } from '@angular/router';
import { ContactComponent } from './contact.component';
// #docregion routing
export const routing = RouterModule.forChild([
export const routing: ModuleWithProviders = RouterModule.forChild([
{ path: 'contact', component: ContactComponent}
]);
// #enddocregion

View File

@ -1,3 +1,4 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes,
RouterModule } from '@angular/router';
@ -10,4 +11,4 @@ const routes: Routes = [
{ path: ':id', component: CrisisDetailComponent }
];
export const routing = RouterModule.forChild(routes);
export const routing: ModuleWithProviders = RouterModule.forChild(routes);

View File

@ -1,3 +1,4 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes,
RouterModule } from '@angular/router';
@ -15,4 +16,4 @@ const routes: Routes = [
}
];
export const routing = RouterModule.forChild(routes);
export const routing: ModuleWithProviders = RouterModule.forChild(routes);

View File

@ -1,3 +1,4 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes,
RouterModule } from '@angular/router';
@ -15,4 +16,4 @@ const routes: Routes = [
}
];
export const routing = RouterModule.forChild(routes);
export const routing: ModuleWithProviders = RouterModule.forChild(routes);

View File

@ -35,7 +35,7 @@
"@angular/router": "3.0.0-rc.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.5",
"angular2-in-memory-web-api": "0.0.15",
"angular2-in-memory-web-api": "0.0.17",
"bootstrap": "^3.3.6",
"core-js": "^2.4.0",
"reflect-metadata": "^0.1.3",

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -64,7 +64,7 @@ describe('Pipes', function () {
});
it('should support flying heroes (pure) ', function () {
xit('should support flying heroes (pure) ', function () {
let nameEle = element(by.css('flying-heroes input[type="text"]'));
let canFlyCheckEle = element(by.css('flying-heroes #can-fly'));
let mutateCheckEle = element(by.css('flying-heroes #mutate'));
@ -95,7 +95,7 @@ describe('Pipes', function () {
});
it('should support flying heroes (impure) ', function () {
xit('should support flying heroes (impure) ', function () {
let nameEle = element(by.css('flying-heroes-impure input[type="text"]'));
let canFlyCheckEle = element(by.css('flying-heroes-impure #can-fly'));
let mutateCheckEle = element(by.css('flying-heroes-impure #mutate'));

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -1,14 +0,0 @@
/* #docregion */
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
body {
margin: 2em;
}
/*
* See https://github.com/angular/angular.io/blob/master/public/docs/_examples/styles.css
* for the full set of master styles used by the documentation samples
*/

View File

@ -1,14 +0,0 @@
/* #docregion */
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
body {
margin: 2em;
}
/*
* See https://github.com/angular/angular.io/blob/master/public/docs/_examples/styles.css
* for the full set of master styles used by the documentation samples
*/

View File

@ -41,7 +41,7 @@
// Bundled (~40 requests):
function packUmd(pkgName) {
packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
packages['@angular/'+pkgName] = { main: 'bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
}
// Most environments should use UMD; some (Karma) need the individual index files

View File

@ -1,5 +1,6 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
// #docregion route-config
import { Routes, RouterModule } from '@angular/router';
@ -36,6 +37,6 @@ export const appRoutingProviders: any[] = [
];
export const routing = RouterModule.forRoot(appRoutes);
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
// #enddocregion route-config
// #enddocregion

View File

@ -1,5 +1,6 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
// #docregion route-config
import { Routes, RouterModule } from '@angular/router';
@ -17,5 +18,5 @@ export const appRoutingProviders: any[] = [
];
export const routing = RouterModule.forRoot(appRoutes);
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
// #enddocregion route-config

View File

@ -1,5 +1,6 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisListComponent } from './crisis-center/crisis-list.component';
@ -12,4 +13,4 @@ export const appRoutingProviders: any[] = [
];
export const routing = RouterModule.forRoot(appRoutes);
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

View File

@ -1,4 +1,5 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const appRoutes: Routes = [
@ -9,4 +10,4 @@ export const appRoutingProviders: any[] = [
];
export const routing = RouterModule.forRoot(appRoutes);
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

View File

@ -1,4 +1,5 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { loginRoutes,
@ -12,4 +13,4 @@ export const appRoutingProviders: any[] = [
authProviders
];
export const routing = RouterModule.forRoot(appRoutes);
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

View File

@ -1,4 +1,5 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
// #docregion import-router
import { Routes, RouterModule } from '@angular/router';
// #enddocregion import-router
@ -32,7 +33,7 @@ export const appRoutingProviders: any[] = [
CanDeactivateGuard
];
export const routing = RouterModule.forRoot(appRoutes);
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
// #enddocregion
/* A link parameters array

View File

@ -1,4 +1,5 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
// #docregion import-router
import { Routes, RouterModule } from '@angular/router';
// #enddocregion import-router
@ -32,4 +33,4 @@ export const appRoutingProviders: any[] = [
CanDeactivateGuard
];
export const routing = RouterModule.forRoot(appRoutes);
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

View File

@ -1,4 +1,5 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
@ -17,5 +18,5 @@ const crisisCenterRoutes: Routes = [
}
];
export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion routes

View File

@ -1,4 +1,5 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
@ -24,5 +25,5 @@ const crisisCenterRoutes: Routes = [
}
];
export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion routes

View File

@ -1,5 +1,6 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
@ -38,7 +39,7 @@ const crisisCenterRoutes: Routes = [
}
];
export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion
/*

View File

@ -1,5 +1,6 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
@ -40,7 +41,7 @@ const crisisCenterRoutes: Routes = [
}
];
export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion
/*

View File

@ -1,5 +1,6 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisCenterComponent } from './crisis-center.component';
@ -49,4 +50,4 @@ const crisisCenterRoutes: Routes = [
}
];
export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);

View File

@ -1,5 +1,6 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisCenterComponent } from './crisis-center.component';
@ -45,6 +46,6 @@ const crisisCenterRoutes: Routes = [
}
];
export const crisisCenterRouting = RouterModule.forChild(crisisCenterRoutes);
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion lazy-load-crisis-center
// #enddocregion

View File

@ -1,4 +1,5 @@
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HeroListComponent } from './hero-list.component';
@ -11,5 +12,5 @@ const heroesRoutes: Routes = [
// #enddocregion hero-detail-route
];
export const heroesRouting = RouterModule.forChild(heroesRoutes);
export const heroesRouting: ModuleWithProviders = RouterModule.forChild(heroesRoutes);
// #enddocregion

View File

@ -1,6 +1,6 @@
// #docregion
import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
browserDynamicPlatform().bootstrapModule(AppModule);
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
http: ^0.11.3+3

View File

@ -14,7 +14,7 @@ import { AppComponent } from './app.component';
JsonpModule
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -2,11 +2,12 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule, JsonpModule, XHRBackend } from '@angular/http';
import { HttpModule, JsonpModule } from '@angular/http';
import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api';
import { HeroData } from './hero-data';
import { AppComponent } from './app.component';
import { InMemoryWebApiModule } from 'angular2-in-memory-web-api';
import { HeroData } from './hero-data';
import { AppComponent } from './app.component';
import { HeroListComponent } from './toh/hero-list.component';
import { HeroListPromiseComponent } from './toh/hero-list.component.promise';
@ -19,11 +20,10 @@ import { WikiSmartComponent } from './wiki/wiki-smart.component';
BrowserModule,
FormsModule,
HttpModule,
JsonpModule
],
providers: [
{ provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
{ provide: SEED_DATA, useClass: HeroData } // in-mem server data
JsonpModule,
// #docregion in-mem-web-api
InMemoryWebApiModule.forRoot(HeroData)
// #enddocregion in-mem-web-api
],
declarations: [
AppComponent,

View File

@ -1,5 +1,6 @@
// #docregion
export class HeroData {
import { InMemoryDbService } from 'angular2-in-memory-web-api';
export class HeroData implements InMemoryDbService {
createDb() {
let heroes = [
{ id: '1', name: 'Windstorm' },

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -1,4 +1,4 @@
import { RouterConfig } from '@angular/router';
import { Routes } from '@angular/router';
import { AppComponent as S0101 } from '../01-01/app';
// import { AppComponent as S0207 } from '../02-07/app';
@ -27,7 +27,7 @@ import { AppComponent as S0101 } from '../01-01/app';
// import { AppComponent as S0704 } from '../07-04/app';
// import { AppComponent as S0901 } from '../09-01/app';
export const routes: RouterConfig = [
export const routes: Routes = [
{ path: '', redirectTo: '/01-01', pathMatch: 'full' },
{ path: '01-01', component: S0101 },
// { path: '02-07', component: S0207 },
@ -56,4 +56,3 @@ export const routes: RouterConfig = [
// { path: '07-04', component: S0704 },
// { path: '09-01', component: S0901 },
];

View File

@ -2,16 +2,14 @@ import { NgModule } from '@angular/core';
import { browserDynamicPlatform } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule,
XHRBackend } from '@angular/http';
import { HttpModule } from '@angular/http';
import { InMemoryWebApiModule } from 'angular2-in-memory-web-api';
import { RouterModule } from '@angular/router';
import { HashLocationStrategy,
LocationStrategy } from '@angular/common';
import { InMemoryBackendService,
SEED_DATA } from 'angular2-in-memory-web-api';
import 'rxjs/add/operator/map';
import { HeroData } from './hero-data';
@ -49,6 +47,7 @@ const moduleMetadata = {
imports: [
BrowserModule,
HttpModule,
InMemoryWebApiModule.forRoot(HeroData),
s0101.AppModule,
s0207.AppModule,
@ -77,17 +76,16 @@ const moduleMetadata = {
s0704.AppModule,
s0901.AppModule,
RouterModule.forRoot([
{ path: '', redirectTo: '/01-01', pathMatch: 'full' }
], {/* enableTracing: true */}),
],
declarations: [AppComponent],
providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy },
{ provide: XHRBackend, useClass: InMemoryBackendService },
{ provide: SEED_DATA, useClass: HeroData }
{ provide: LocationStrategy, useClass: HashLocationStrategy }
],
bootstrap: [ AppComponent ]
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
};
@NgModule(moduleMetadata)

View File

@ -1,3 +1,4 @@
/* #docregion , quickstart, toh */
/* Master Styles */
h1 {
color: #369;
@ -12,10 +13,12 @@ h2, h3 {
body {
margin: 2em;
}
/* #enddocregion quickstart */
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}
/* #enddocregion toh */
a {
cursor: pointer;
cursor: hand;
@ -135,7 +138,7 @@ nav a.active {
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
/* #docregion toh */
/* everywhere else */
* {
font-family: Arial, Helvetica, sans-serif;

View File

@ -40,7 +40,7 @@
// Bundled (~40 requests):
function packUmd(pkgName) {
packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
packages['@angular/'+pkgName] = { main: 'bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
}
// Most environments should use UMD; some (Karma) need the individual index files

View File

@ -108,8 +108,7 @@ class AppComponent implements OnInit, AfterViewInit {
bool onSave([UIEvent event = null]) {
HtmlElement el = event?.target;
var evtMsg =
event != null ? ' Event target is ${el.innerHtml}.' : '';
var evtMsg = event != null ? ' Event target is ${el.innerHtml}.' : '';
alerter('Saved. $evtMsg');
return false;
}
@ -126,8 +125,12 @@ class AppComponent implements OnInit, AfterViewInit {
}
String getStyles(Element el) {
var showStyles = setStyles();
return JSON.encode(showStyles);
final style = el.style;
final Map styles = <String, String>{};
for (var i = 0; i < style.length; i++) {
styles[style.item(i)] = style.getPropertyValue(style.item(i));
}
return JSON.encode(styles);
}
Map<String, bool> _previousClasses = {};
@ -140,8 +143,8 @@ class AppComponent implements OnInit, AfterViewInit {
};
// #docregion setClasses
// compensate for DevMode (sigh)
if (JSON.encode(_previousClasses) ==
JSON.encode(classes)) return _previousClasses;
if (JSON.encode(_previousClasses) == JSON.encode(classes))
return _previousClasses;
_previousClasses = classes;
// #enddocregion setClasses
return classes;
@ -149,8 +152,8 @@ class AppComponent implements OnInit, AfterViewInit {
// #enddocregion setClasses
// #docregion setStyles
Map setStyles() {
return {
Map<String, String> setStyles() {
return <String, String>{
'font-style': canSave ? 'italic' : 'normal', // italic
'font-weight': !isUnchanged ? 'bold' : 'normal', // normal
'font-size': isSpecial ? '24px' : '8px' // 24px
@ -158,8 +161,27 @@ class AppComponent implements OnInit, AfterViewInit {
}
// #enddocregion setStyles
// #docregion NgStyle
bool isItalic = false;
bool isBold = false;
String fontSize = 'large';
Map<String, String> setStyle() {
return {
'font-style': isItalic ? 'italic' : 'normal',
'font-weight': isBold ? 'bold' : 'normal',
'font-size': fontSize
};
}
// #enddocregion NgStyle
String title = 'Template Syntax';
// #docregion evil-title
String evilTitle = 'Template <script>alert("evil never sleeps")</script>Syntax';
// #enddocregion evil-title
String toeChoice;
String toeChooser(Element picker) {
List<Element> choices = picker.children;
for (var i = 0; i < choices.length; i++) {
@ -187,13 +209,16 @@ class AppComponent implements OnInit, AfterViewInit {
int heroesNoTrackByChangeCount = 0;
int heroesWithTrackByChangeCount = 0;
@ViewChildren('noTrackBy') QueryList<ElementRef> childrenNoTrackBy;
@ViewChildren('withTrackBy') QueryList<ElementRef> childrenWithTrackBy;
@ViewChildren('noTrackBy')
QueryList<ElementRef> childrenNoTrackBy;
@ViewChildren('withTrackBy')
QueryList<ElementRef> childrenWithTrackBy;
void _detectNgForTrackByEffects() {
/// Converts [viewChildren] to a list of [Element].
List<Element> _extractChildren(QueryList<ElementRef> viewChildren) =>
viewChildren.toList()[0].nativeElement.children.toList() as List<Element>;
viewChildren.toList()[0].nativeElement.children.toList()
as List<Element>;
{
// Updates 'without TrackBy' statistics.

View File

@ -197,13 +197,18 @@ button</button>
<!-- #enddocregion property-binding-7 -->
<!-- #docregion property-binding-vs-interpolation -->
Interpolated: <img src="{{heroImageUrl}}"><br>
Property bound: <img [src]="heroImageUrl">
<p><img src="{{heroImageUrl}}"> is the <i>interpolated</i> image.</p>
<p><img [src]="heroImageUrl"> is the <i>property bound</i> image.</p>
<div>The interpolated title is {{title}}</div>
<div [innerHTML]="'The [innerHTML] title is '+title"></div>
<p><span>"{{title}}" is the <i>interpolated</i> title.</span></p>
<p>"<span [innerHTML]="title"></span>" is the <i>property bound</i> title.</p>
<!-- #enddocregion property-binding-vs-interpolation -->
<!-- #docregion property-binding-vs-interpolation-sanitization -->
<p><span>"{{evilTitle}}" is the <i>interpolated</i> evil title.</span></p>
<p>"<span [innerHTML]="evilTitle"></span>" is the <i>property bound</i> evil title.</p>
<!-- #enddocregion property-binding-vs-interpolation-sanitization -->
<a class="to-toc" href="#toc">top</a>
<!-- attribute binding -->
@ -409,6 +414,18 @@ bindon-ngModel
<!-- NgStyle binding -->
<hr><h2 id="ngStyle">NgStyle Binding</h2>
<!-- #docregion NgStyle -->
<div>
<p [ngStyle]="setStyle()" #styleP>Change style of this text!</p>
<label>Italic: <input type="checkbox" [(ngModel)]="isItalic"></label> |
<label>Bold: <input type="checkbox" [(ngModel)]="isBold"></label> |
<label>Size: <input type="text" [(ngModel)]="fontSize"></label>
<p>Style set to: <code>'{{styleP.style.cssText}}'</code></p>
</div>
<!-- #enddocregion NgStyle -->
<!-- #docregion NgStyle-1 -->
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >
This div is x-large.

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -19,7 +19,7 @@ class Hero {
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
name: _name.substr(0, _name.indexOf(' '))
name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -31,7 +31,7 @@ class Hero {
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
name: _name.substr(0, _name.indexOf(' '))
name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}

View File

@ -40,7 +40,7 @@
// #enddocregion ng-if
// #docregion hero-array-1
public heroes = HEROES;
heroes = HEROES;
// #enddocregion hero-array-1
// #docregion heroes-template-1

View File

@ -102,6 +102,8 @@ export class AppComponent {
// #enddocregion selected-hero
// #docregion on-select
onSelect(hero: Hero) { this.selectedHero = hero; }
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
// #enddocregion on-select
}

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -31,7 +31,7 @@ class Hero {
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
name: _name.substr(0, _name.indexOf(' '))
name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}

View File

@ -89,5 +89,7 @@ export class AppComponent {
heroes = HEROES;
selectedHero: Hero;
onSelect(hero: Hero) { this.selectedHero = hero; }
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
}

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -31,7 +31,7 @@ class Hero {
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
name: _name.substr(0, _name.indexOf(' '))
name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}

View File

@ -7,7 +7,7 @@ import { Component } from '@angular/core';
import { Hero } from './hero';
// #docregion hero-service-import
import { HeroService } from './hero.service.1';
import { HeroService } from './hero.service.2';
// #enddocregion hero-service-import
// Testable but never shown
@ -41,7 +41,7 @@ export class AppComponent implements OnInit {
constructor(private heroService: HeroService) { }
// #enddocregion ctor
// #docregion getHeroes
getHeroes() {
getHeroes(): void {
// #docregion get-heroes
this.heroes = this.heroService.getHeroes();
// #enddocregion get-heroes
@ -50,7 +50,7 @@ export class AppComponent implements OnInit {
// #docregion ng-on-init
// #docregion on-init
ngOnInit() {
ngOnInit(): void {
// #enddocregion on-init
this.getHeroes();
// #docregion on-init
@ -58,6 +58,8 @@ export class AppComponent implements OnInit {
// #enddocregion on-init
// #enddocregion ng-on-init
onSelect(hero: Hero) { this.selectedHero = hero; }
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
// #docregion on-init
}

View File

@ -82,14 +82,16 @@ export class AppComponent implements OnInit {
constructor(private heroService: HeroService) { }
// #docregion get-heroes
getHeroes() {
getHeroes(): void {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
// #enddocregion get-heroes
ngOnInit() {
ngOnInit(): void {
this.getHeroes();
}
onSelect(hero: Hero) { this.selectedHero = hero; }
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
}

View File

@ -1,19 +1,25 @@
// #docplaster
// #docregion
// #docregion empty-class
// #docregion empty-class, full
import { Injectable } from '@angular/core';
// #enddocregion empty-class
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
// #docregion empty-class, getHeroes-stub
@Injectable()
export class HeroService {
// #enddocregion empty-class
getHeroes() {
// #enddocregion getHeroes-stub
return HEROES;
// #docregion getHeroes-stub
// #enddocregion empty-class, getHeroes-stub, full
/*
// #docregion getHeroes-stub
getHeroes(): void {
}
// #docregion empty-class
// #enddocregion getHeroes-stub
*/
// #docregion full
getHeroes(): Hero[] {
return HEROES;
}
// #docregion empty-class, getHeroes-stub
}

View File

@ -0,0 +1,13 @@
// #docregion
import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
@Injectable()
export class HeroService {
getHeroes(): Hero[] {
return HEROES;
}
}

View File

@ -9,14 +9,14 @@ import { HEROES } from './mock-heroes';
@Injectable()
export class HeroService {
// #docregion get-heroes
getHeroes() {
getHeroes(): Promise<Hero[]> {
return Promise.resolve(HEROES);
}
// #enddocregion get-heroes, just-get-heroes
// #enddocregion
// See the "Take it slow" appendix
// #docregion get-heroes-slowly
getHeroesSlowly() {
getHeroesSlowly(): Promise<Hero[]> {
return new Promise<Hero[]>(resolve =>
setTimeout(() => resolve(HEROES), 2000) // 2 seconds
);

View File

@ -1,18 +1,18 @@
// #docplaster
// #docregion
import 'package:angular2/core.dart';
// #docregion import-router
import 'package:angular2/router.dart';
// #enddocregion import-router
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
import 'dashboard_component.dart';
import 'hero_detail_component.dart';
import 'hero_service.dart';
import 'heroes_component.dart';
@Component(
selector: 'my-app',
// #docregion template
// #docregion template, template-v3
template: '''
<h1>{{title}}</h1>
<nav>
@ -20,26 +20,32 @@ import 'package:angular2_tour_of_heroes/hero_detail_component.dart';
<a [routerLink]="['Heroes']">Heroes</a>
</nav>
<router-outlet></router-outlet>''',
// #enddocregion template
// #docregion style-urls
// #enddocregion template, template-v3
// #docregion styleUrls
styleUrls: const ['app_component.css'],
// #enddocregion style-urls
// #enddocregion styleUrls
// #docregion directives-and-providers
directives: const [ROUTER_DIRECTIVES],
providers: const [HeroService, ROUTER_PROVIDERS])
// #enddocregion directives-and-providers
// #docregion heroes
@RouteConfig(const [
// #docregion dashboard-route
// #enddocregion heroes
// #docregion dashboard
const Route(
path: '/dashboard',
name: 'Dashboard',
component: DashboardComponent,
useAsDefault: true),
// #enddocregion dashboard-route
// #docregion hero-detail-route
// #enddocregion dashboard
// #docregion hero-detail
const Route(
path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent),
// #enddocregion hero-detail-route
// #enddocregion hero-detail
// #docregion heroes
const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
])
// #enddocregion heroes
class AppComponent {
String title = 'Tour of Heroes';
}

View File

@ -1,25 +1,40 @@
// #docplaster
// #docregion
// #docregion , v2
import 'package:angular2/core.dart';
// #enddocregion
import 'package:angular2/router.dart'; // for testing only
// #enddocregion ,
// #docregion v2
import 'package:angular2/router.dart';
// #docregion
import 'hero_service.dart';
import 'heroes_component.dart';
// #enddocregion v2
@Component(
selector: 'my-app',
template: '''
<h1>{{title}}</h1>
<my-heroes></my-heroes>''',
directives: const [HeroesComponent],
providers: const [
// #enddocregion
ROUTER_PROVIDERS,
// #docregion
HeroService
])
providers: const [HeroService])
// #enddocregion ,
class Bogus {}
// #docregion v2
@Component(
selector: 'my-app',
// #docregion template-v2
template: '''
<h1>{{title}}</h1>
<a [routerLink]="['Heroes']">Heroes</a>
<router-outlet></router-outlet>''',
// #enddocregion template-v2
directives: const [ROUTER_DIRECTIVES],
providers: const [HeroService, ROUTER_PROVIDERS])
@RouteConfig(const [
const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
])
// #docregion ,
class AppComponent {
String title = 'Tour of Heroes';
}

View File

@ -1,31 +0,0 @@
// #docplaster
// #docregion
import 'package:angular2/core.dart';
// #docregion import-router
import 'package:angular2/router.dart';
// #enddocregion import-router
import 'hero_service.dart';
import 'heroes_component.dart';
@Component(
selector: 'my-app',
// #docregion template
template: '''
<h1>{{title}}</h1>
<a [routerLink]="['Heroes']">Heroes</a>
<router-outlet></router-outlet>''',
// #enddocregion template
// #docregion directives-and-providers
directives: const [ROUTER_DIRECTIVES],
providers: const [ROUTER_PROVIDERS, HeroService]
// #enddocregion directives-and-providers
)
// #docregion route-config
@RouteConfig(const [
const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)
])
// #enddocregion route-config
class AppComponent {
String title = 'Tour of Heroes';
}

View File

@ -12,9 +12,9 @@ import 'hero_service.dart';
@Component(
selector: 'my-dashboard',
// #docregion template-url
// #docregion templateUrl
templateUrl: 'dashboard_component.html',
// #enddocregion template-url
// #enddocregion templateUrl
// #docregion css
styleUrls: const ['dashboard_component.css']
// #enddocregion css
@ -35,7 +35,7 @@ class DashboardComponent implements OnInit {
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
}
// #docregion goto-detail
// #docregion gotoDetail
void gotoDetail(Hero hero) {
var link = [
'HeroDetail',
@ -43,5 +43,5 @@ class DashboardComponent implements OnInit {
];
_router.navigate(link);
}
// #enddocregion goto-detail
// #enddocregion gotoDetail
}

View File

@ -22,5 +22,5 @@ class DashboardComponent implements OnInit {
heroes = (await _heroService.getHeroes()).skip(1).take(4).toList();
}
gotoDetail() {/* not implemented yet */}
gotoDetail(Hero hero) {/* not implemented yet */}
}

View File

@ -1,30 +1,28 @@
// #docplaster
// #docregion , v2
// #docregion added-imports
import 'dart:async';
import 'dart:html';
import 'dart:html' show window;
// #docregion import-oninit
// #enddocregion added-imports
import 'package:angular2/core.dart';
// #enddocregion import-oninit
// #docregion import-route-params
// #docregion added-imports
import 'package:angular2/router.dart';
// #enddocregion import-route-params
// #enddocregion added-imports
import 'hero.dart';
// #docregion import-hero-service
// #docregion added-imports
import 'hero_service.dart';
// #enddocregion import-hero-service
// #enddocregion added-imports
// #docregion extract-template
@Component(
selector: 'my-hero-detail',
// #docregion template-url
// #docregion templateUrl
templateUrl: 'hero_detail_component.html',
// #enddocregion template-url, v2
// #enddocregion templateUrl, v2
styleUrls: const ['hero_detail_component.css']
// #docregion v2
)
// #enddocregion extract-template
// #docregion implement
class HeroDetailComponent implements OnInit {
// #enddocregion implement
@ -36,19 +34,17 @@ class HeroDetailComponent implements OnInit {
HeroDetailComponent(this._heroService, this._routeParams);
// #enddocregion ctor
// #docregion ng-oninit
// #docregion ngOnInit
Future<Null> ngOnInit() async {
// #docregion get-id
var idString = _routeParams.get('id');
var id = int.parse(idString, onError: (_) => null);
// #enddocregion get-id
var id = int.parse(idString ?? '', onError: (_) => null);
if (id != null) hero = await (_heroService.getHero(id));
}
// #enddocregion ng-oninit
// #enddocregion ngOnInit
// #docregion go-back
// #docregion goBack
void goBack() {
window.history.back();
}
// #enddocregion go-back
// #enddocregion goBack
}

View File

@ -16,8 +16,8 @@ class HeroService {
const Duration(seconds: 2), () => mockHeroes);
}
// #docregion get-hero
// #docregion getHero
Future<Hero> getHero(int id) async =>
(await getHeroes()).firstWhere((hero) => hero.id == id);
// #enddocregion get-hero
// #enddocregion getHero
}

View File

@ -6,27 +6,28 @@ import 'package:angular2/core.dart';
import 'package:angular2/router.dart';
import 'hero.dart';
import 'hero_detail_component.dart';
import 'hero_service.dart';
// #docregion metadata, heroes-component-renaming
// #docregion metadata, renaming
@Component(
selector: 'my-heroes',
// #enddocregion heroes-component-renaming
// #enddocregion renaming
templateUrl: 'heroes_component.html',
styleUrls: const ['heroes_component.css'],
directives: const [HeroDetailComponent])
// #docregion heroes-component-renaming
// #enddocregion heroes-component-renaming, metadata
// #docregion class, heroes-component-renaming
styleUrls: const ['heroes_component.css']
// #docregion renaming
)
// #enddocregion metadata
// #docregion class
class HeroesComponent implements OnInit {
// #enddocregion heroes-component-renaming
// #enddocregion renaming
final Router _router;
final HeroService _heroService;
List<Hero> heroes;
Hero selectedHero;
// #docregion renaming
HeroesComponent(this._heroService, this._router);
// #enddocregion renaming
Future<Null> getHeroes() async {
heroes = await _heroService.getHeroes();
@ -44,5 +45,5 @@ class HeroesComponent implements OnInit {
'HeroDetail',
{'id': selectedHero.id.toString()}
]);
// #docregion heroes-component-renaming
// #docregion renaming
}

View File

@ -5,7 +5,7 @@ version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.18
angular2: 2.0.0-beta.20
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:

View File

@ -1,24 +0,0 @@
/* #docregion toh-excerpt */
/* Master Styles */
h1 {
color: #369;
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
}
h2, h3 {
color: #444;
font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
}
body {
margin: 2em;
}
body, input[text], button {
color: #888;
font-family: Cambria, Georgia;
}
/* . . . */
/* everywhere else */
* {
font-family: Arial, Helvetica, sans-serif;
}

View File

@ -1,113 +1,190 @@
/// <reference path='../_protractor/e2e.d.ts' />
'use strict';
describe('Tutorial', function () {
beforeAll(function () {
browser.get('');
});
const expectedH1 = 'Tour of Heroes';
const expectedTitle = `Angular 2 ${expectedH1}`;
const targetHero = { id: 15, name: 'Magneta' };
const targetHeroDashboardIndex = 3;
const nameSuffix = 'X';
const newHeroName = targetHero.name + nameSuffix;
function getPageStruct() {
let hrefEles = element.all(by.css('my-app a'));
type WPromise<T> = webdriver.promise.Promise<T>;
class Hero {
id: number;
name: string;
// Factory methods
// Get hero from s formatted as '<id> <name>'.
static fromString(s: string): Hero {
return {
id: +s.substr(0, s.indexOf(' ')),
name: s.substr(s.indexOf(' ') + 1),
};
}
// Get hero id and name from the given detail element.
static async fromDetail(detail: protractor.ElementFinder): Promise<Hero> {
// Get hero id from the first <div>
let _id = await detail.all(by.css('div')).first().getText();
// Get name from the h2
let _name = await detail.element(by.css('h2')).getText();
return {
id: +_id.substr(_id.indexOf(' ') + 1),
name: _name.substr(0, _name.lastIndexOf(' '))
};
}
}
describe('Tutorial part 5', () => {
beforeAll(() => browser.get(''));
function getPageElts() {
let hrefElts = element.all(by.css('my-app a'));
return {
hrefs: hrefEles,
myDashboardHref: hrefEles.get(0),
myDashboardParent: element(by.css('my-app my-dashboard')),
topHeroes: element.all(by.css('my-app my-dashboard .module.hero')),
hrefs: hrefElts,
myHeroesHref: hrefEles.get(1),
myHeroesParent: element(by.css('my-app my-heroes')),
myDashboardHref: hrefElts.get(0),
myDashboard: element(by.css('my-app my-dashboard')),
topHeroes: element.all(by.css('my-app my-dashboard > div h4')),
myHeroesHref: hrefElts.get(1),
myHeroes: element(by.css('my-app my-heroes')),
allHeroes: element.all(by.css('my-app my-heroes li')),
selectedHero: element(by.css('my-app li.selected')),
selectedHeroSubview: element(by.css('my-app my-heroes > div')),
heroDetail: element(by.css('my-app my-hero-detail'))
heroDetail: element(by.css('my-app my-hero-detail > div'))
};
}
it('should be able to see the start screen', function () {
let page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.myDashboardHref.getText()).toEqual('Dashboard');
expect(page.myHeroesHref.getText()).toEqual('Heroes');
});
describe('Initial page', () => {
it('should be able to see dashboard choices', function () {
let page = getPageStruct();
expect(page.topHeroes.count()).toBe(4, 'should be 4 dashboard hero choices');
});
it(`has title '${expectedTitle}'`, () => {
expect(browser.getTitle()).toEqual(expectedTitle);
});
it('should be able to toggle the views', function () {
let page = getPageStruct();
it(`has h1 '${expectedH1}'`, () => {
expectHeading(1, expectedH1);
});
expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes');
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element');
expect(page.allHeroes.count()).toBeGreaterThan(4, 'should be more than 4 heroes shown');
return page.myDashboardHref.click();
}).then(function() {
expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element');
const expectedViewNames = ['Dashboard', 'Heroes'];
it(`has views ${expectedViewNames}`, () => {
let viewNames = getPageElts().hrefs.map(el => el.getText());
expect(viewNames).toEqual(expectedViewNames);
});
it('has dashboard as the active view', () => {
let page = getPageElts();
expect(page.myDashboard.isPresent()).toBeTruthy();
});
});
it('should be able to edit details from "Dashboard" view', function () {
let page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
let heroEle = page.topHeroes.get(3);
let heroDescrEle = heroEle.element(by.css('h4'));
let heroDescr: string;
return heroDescrEle.getText().then(function(text) {
heroDescr = text;
return heroEle.click();
}).then(function() {
return editDetails(page, heroDescr, '-foo');
}).then(function() {
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back');
expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo');
describe('Dashboard tests', () => {
beforeAll(() => browser.get(''));
it('has top heroes', () => {
let page = getPageElts();
expect(page.topHeroes.count()).toEqual(4);
});
it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero);
it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView);
it(`saves and shows ${newHeroName} in Dashboard`, () => {
element(by.buttonText('Back')).click();
let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex);
expect(targetHeroElt.getText()).toEqual(newHeroName);
});
});
it('should be able to edit details from "Heroes" view', function () {
let page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present');
let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
let heroEle: protractor.ElementFinder;
let heroDescr: string;
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present');
expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present');
heroEle = page.allHeroes.get(2);
return heroEle.getText();
}).then(function(text) {
// remove leading 'id' from the element
heroDescr = text.substr(text.indexOf(' ') + 1);
return heroEle.click();
}).then(function() {
expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible');
return viewDetailsButtonEle.click();
}).then(function() {
return editDetails(page, heroDescr, '-bar');
}).then(function() {
expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be back');
expect(heroEle.getText()).toContain(heroDescr + '-bar');
expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should again NOT be present');
describe('Heroes tests', () => {
beforeAll(() => browser.get(''));
it('can switch to Heroes view', () => {
getPageElts().myHeroesHref.click();
let page = getPageElts();
expect(page.myHeroes.isPresent()).toBeTruthy();
expect(page.allHeroes.count()).toEqual(10, 'number of heroes');
});
it(`selects and shows ${targetHero.name} as selected in list`, () => {
getHeroLiEltById(targetHero.id).click();
let expectedText = `${targetHero.id} ${targetHero.name}`;
expect(getPageElts().selectedHero.getText()).toBe(expectedText);
});
it('shows selected hero subview', async () => {
let page = getPageElts();
let title = page.selectedHeroSubview.element(by.css('h2')).getText();
let expectedTitle = `${targetHero.name.toUpperCase()} is my hero`;
expect(title).toEqual(expectedTitle);
});
it('can route to hero details', async () => {
element(by.buttonText('View Details')).click();
let page = getPageElts();
expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail');
let hero = await Hero.fromDetail(page.heroDetail);
expect(hero.id).toEqual(targetHero.id);
expect(hero.name).toEqual(targetHero.name);
});
it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView);
it(`shows ${newHeroName} in Heroes list`, () => {
element(by.buttonText('Back')).click();
let expectedText = `${targetHero.id} ${newHeroName}`;
expect(getHeroLiEltById(targetHero.id).getText()).toEqual(expectedText);
});
});
function editDetails(page: any, origValue: string, textToAdd: string) {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present');
expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details');
let inputEle = page.heroDetail.element(by.css('input'));
expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
let backButtonEle = page.heroDetail.element(by.css('button'));
expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
let detailTextEle = page.heroDetail.element(by.css('div h2'));
expect(detailTextEle.getText()).toContain(origValue);
return sendKeys(inputEle, textToAdd).then(function () {
expect(detailTextEle.getText()).toContain(origValue + textToAdd);
return backButtonEle.click();
});
async function dashboardSelectTargetHero() {
let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex);
expect(targetHeroElt.getText()).toEqual(targetHero.name);
targetHeroElt.click();
let page = getPageElts();
expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail');
let hero = await Hero.fromDetail(page.heroDetail);
expect(hero.id).toEqual(targetHero.id);
expect(hero.name).toEqual(targetHero.name);
}
async function updateHeroNameInDetailView() {
// Assumes that the current view is the hero details view.
addToHeroName(nameSuffix);
let page = getPageElts();
let hero = await Hero.fromDetail(page.heroDetail);
expect(hero.id).toEqual(targetHero.id);
expect(hero.name).toEqual(newHeroName);
}
});
function addToHeroName(text: string): WPromise<void> {
let input = element(by.css('input'));
return sendKeys(input, text);
}
function expectHeading(hLevel: number, expectedText: string): void {
let hTag = `h${hLevel}`;
let hText = element(by.css(hTag)).getText();
expect(hText).toEqual(expectedText, hTag);
};
function getHeroLiEltById(id: number) {
let spanForId = element(by.cssContainingText('li span.badge', id.toString()));
return spanForId.element(by.xpath('..'));
}

View File

@ -1,7 +1,8 @@
// #docplaster
// #docregion
// #docregion , v2
import { Component } from '@angular/core';
// #enddocregion v2
@Component({
selector: 'my-app',
template: `
@ -9,6 +10,33 @@ import { Component } from '@angular/core';
<my-heroes></my-heroes>
`
})
// #enddocregion
// #docregion v2
@Component({
selector: 'my-app',
// #docregion template-v2
template: `
<h1>{{title}}</h1>
<a routerLink="/heroes">Heroes</a>
<router-outlet></router-outlet>
`
// #enddocregion template-v2
})
// #enddocregion
@Component({
selector: 'my-app',
// #docregion template-v3
template: `
<h1>{{title}}</h1>
<nav>
<a routerLink="/dashboard">Dashboard</a>
<a routerLink="/heroes">Heroes</a>
</nav>
<router-outlet></router-outlet>
`
// #enddocregion template-v3
})
// #docregion , v2
export class AppComponent {
title = 'Tour of Heroes';
}

View File

@ -1,17 +0,0 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1>{{title}}</h1>
<a routerLink="/heroes">Heroes</a>
<router-outlet></router-outlet>
`
// #enddocregion template
})
export class AppComponent {
title = 'Tour of Heroes';
}

View File

@ -1,24 +0,0 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1>{{title}}</h1>
<nav>
<a routerLink="/dashboard">Dashboard</a>
<a routerLink="/heroes">Heroes</a>
</nav>
<router-outlet></router-outlet>
`,
// #enddocregion template
// #docregion style-urls
styleUrls: ['app/app.component.css'],
// #enddocregion style-urls
})
export class AppComponent {
title = 'Tour of Heroes';
}
// #enddocregion

View File

@ -1,4 +1,3 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
@ -14,9 +13,9 @@ import { Component } from '@angular/core';
<router-outlet></router-outlet>
`,
// #enddocregion template
// #docregion style-urls
// #docregion styleUrls
styleUrls: ['app/app.component.css'],
// #enddocregion style-urls
// #enddocregion styleUrls
})
export class AppComponent {
title = 'Tour of Heroes';

View File

@ -3,11 +3,10 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HeroesComponent } from './heroes.component';
import { HeroService } from './hero.service';
import { AppComponent } from './app.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroesComponent } from './heroes.component';
import { HeroService } from './hero.service';
@NgModule({
imports: [
@ -16,6 +15,7 @@ import { HeroService } from './hero.service';
],
declarations: [
AppComponent,
HeroDetailComponent,
HeroesComponent
],
providers: [

View File

@ -1,30 +0,0 @@
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { HeroesComponent } from './heroes.component';
import { HeroService } from './hero.service';
@NgModule({
imports: [
BrowserModule,
FormsModule,
routing
],
declarations: [
AppComponent,
HeroesComponent
],
providers: [
HeroService
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
// #enddocregion

View File

@ -1,47 +0,0 @@
// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { HeroesComponent } from './heroes.component';
// #docregion dashboard-declaration
import { DashboardComponent } from './dashboard.component';
// #enddocregion dashboard-declaration
// #docregion hero-detail-declaration
import { HeroDetailComponent } from './hero-detail.component';
// #enddocregion hero-detail-declaration
import { HeroService } from './hero.service';
@NgModule({
imports: [
BrowserModule,
FormsModule,
routing
],
// #docregion dashboard-declaration, hero-detail-declaration
declarations: [
// #enddocregion dashboard-declaration, hero-detail-declaration
AppComponent,
HeroesComponent,
// #docregion dashboard-declaration
DashboardComponent,
// #enddocregion dashboard-declaration
// #docregion hero-detail-declaration
HeroDetailComponent
// #enddocregion hero-detail-declaration
// #docregion dashboard-declaration, hero-detail-declaration
],
// #enddocregion dashboard-declaration, hero-detail-declaration
providers: [
HeroService
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
// #enddocregion

View File

@ -1,16 +1,17 @@
// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { HeroesComponent } from './heroes.component';
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroService } from './hero.service';
import { HeroesComponent } from './heroes.component';
import { HeroService } from './hero.service';
// #docregion routing
import { routing } from './app.routing';
// #docregion routing
@NgModule({
imports: [
@ -18,17 +19,20 @@ import { HeroService } from './hero.service';
FormsModule,
routing
],
// #enddocregion routing
// #docregion dashboard, hero-detail
declarations: [
AppComponent,
HeroesComponent,
DashboardComponent,
HeroDetailComponent
HeroDetailComponent,
HeroesComponent
],
// #enddocregion dashboard, hero-detail
providers: [
HeroService
],
bootstrap: [ AppComponent ]
// #docregion routing
})
export class AppModule {
}
// #enddocregion

Some files were not shown because too many files have changed in this diff Show More