Merge remote-tracking branch 'origin/master'
# Conflicts: # public/docs/ts/latest/guide/style-guide.jade # public/docs/ts/latest/tutorial/toh-pt1.jade # public/docs/ts/latest/tutorial/toh-pt2.jade # public/docs/ts/latest/tutorial/toh-pt3.jade # public/docs/ts/latest/tutorial/toh-pt4.jade # public/docs/ts/latest/tutorial/toh-pt5.jade
This commit is contained in:
commit
7995cb4897
|
@ -12,6 +12,7 @@ pubspec.lock
|
|||
.DS_Store
|
||||
**/*.iml
|
||||
.idea
|
||||
.vscode
|
||||
**/js/latest/api
|
||||
**/ts/latest/api
|
||||
**/dart/latest/api
|
||||
|
@ -21,8 +22,7 @@ _.*
|
|||
public/docs/xref-*.*
|
||||
_zip-output
|
||||
www
|
||||
npm-debug.log
|
||||
npm-debug.log.*
|
||||
npm-debug*.log*
|
||||
*.plnkr.html
|
||||
plnkr.html
|
||||
*plnkr.no-link.html
|
||||
|
|
|
@ -10,6 +10,7 @@ env:
|
|||
- DISPLAY=:99.0
|
||||
- CHROME_BIN=chromium-browser
|
||||
matrix:
|
||||
- SCRIPT="lint"
|
||||
- SCRIPT="run-e2e-tests --fast"
|
||||
before_install:
|
||||
- npm install -g gulp --no-optional
|
||||
|
@ -22,4 +23,4 @@ install:
|
|||
- npm run webdriver:update --prefix public/docs/_examples/_protractor
|
||||
- gulp add-example-boilerplate
|
||||
script:
|
||||
- gulp $SCRIPT
|
||||
- gulp $SCRIPT
|
||||
|
|
62
gulpfile.js
62
gulpfile.js
|
@ -89,6 +89,18 @@ var _exampleProtractorBoilerplateFiles = [
|
|||
'tsconfig.json'
|
||||
];
|
||||
|
||||
var _exampleConfigFilename = 'example-config.json';
|
||||
|
||||
function isDartPath(path) {
|
||||
// Testing via indexOf() for now. If we need to match only paths with folders
|
||||
// named 'dart' vs 'dart*' then try: path.match('/dart(/|$)') != null;
|
||||
return path.indexOf('/dart') > -1;
|
||||
}
|
||||
|
||||
function excludeDartPaths(paths) {
|
||||
return paths.filter(function (p) { return !isDartPath(p); });
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Protractor End-to-End Specs for Doc Samples
|
||||
* Alias for 'run-e2e-tests'
|
||||
|
@ -165,7 +177,6 @@ function runE2e() {
|
|||
// with the corresponding apps that they should run under. Then run
|
||||
// each app/spec collection sequentially.
|
||||
function findAndRunE2eTests(filter, outputFile) {
|
||||
|
||||
// create an output file with header.
|
||||
var lang = (argv.lang || '(ts|js)').toLowerCase();
|
||||
if (lang === 'all') { lang = '(ts|js|dart)'; }
|
||||
|
@ -203,8 +214,7 @@ function findAndRunE2eTests(filter, outputFile) {
|
|||
var status = { passed: [], failed: [] };
|
||||
return examplePaths.reduce(function (promise, examplePath) {
|
||||
return promise.then(function () {
|
||||
var isDart = examplePath.indexOf('/dart') > -1;
|
||||
var runTests = isDart ? runE2eDartTests : runE2eTsTests;
|
||||
var runTests = isDartPath(examplePath) ? runE2eDartTests : runE2eTsTests;
|
||||
return runTests(examplePath, outputFile).then(function(ok) {
|
||||
var arr = ok ? status.passed : status.failed;
|
||||
arr.push(examplePath);
|
||||
|
@ -221,18 +231,19 @@ function findAndRunE2eTests(filter, outputFile) {
|
|||
// fileName; then shut down the example. All protractor output is appended
|
||||
// to the outputFile.
|
||||
function runE2eTsTests(appDir, outputFile) {
|
||||
// spawn tasks to start the app
|
||||
var appBuildSpawnInfo;
|
||||
var appRunSpawnInfo;
|
||||
|
||||
if (fs.existsSync(path.join(appDir, 'angular-cli.json'))) {
|
||||
appBuildSpawnInfo = spawnExt('npm', ['run', 'build:cli'], { cwd: appDir });
|
||||
appRunSpawnInfo = spawnExt('npm', ['run', 'http-server:cli', '--', '-s'], { cwd: appDir });
|
||||
} else {
|
||||
appBuildSpawnInfo = spawnExt('npm',['run','tsc'], { cwd: appDir });
|
||||
appRunSpawnInfo = spawnExt('npm',['run','http-server:e2e', '--', '-s' ], { cwd: appDir });
|
||||
// Grab protractor configuration or defaults to systemjs config.
|
||||
try {
|
||||
var exampleConfig = fs.readJsonSync(`${appDir}/${_exampleConfigFilename}`);
|
||||
} catch (e) {
|
||||
exampleConfig = {
|
||||
build: 'tsc',
|
||||
run: 'http-server:e2e'
|
||||
};
|
||||
}
|
||||
|
||||
var appBuildSpawnInfo = spawnExt('npm', ['run', exampleConfig.build], { cwd: appDir });
|
||||
var appRunSpawnInfo = spawnExt('npm', ['run', exampleConfig.run, '--', '-s'], { cwd: appDir });
|
||||
|
||||
return runProtractor(appBuildSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile);
|
||||
}
|
||||
|
||||
|
@ -375,7 +386,7 @@ gulp.task('add-example-boilerplate', function() {
|
|||
});
|
||||
|
||||
realPath = path.join(EXAMPLES_PATH, '/typings');
|
||||
var typingsPaths = getTypingsPaths(EXAMPLES_PATH);
|
||||
var typingsPaths = excludeDartPaths(getTypingsPaths(EXAMPLES_PATH));
|
||||
typingsPaths.forEach(function(linkPath) {
|
||||
gutil.log("symlinking " + linkPath + ' -> ' + realPath)
|
||||
fsUtils.addSymlink(realPath, linkPath);
|
||||
|
@ -398,16 +409,18 @@ function copyExampleBoilerplate() {
|
|||
var sourceFiles = _exampleBoilerplateFiles.map(function(fn) {
|
||||
return path.join(EXAMPLES_PATH, fn);
|
||||
});
|
||||
var examplePaths = getExamplePaths(EXAMPLES_PATH);
|
||||
var examplePaths = excludeDartPaths(getExamplePaths(EXAMPLES_PATH));
|
||||
|
||||
var dartWebSourceFiles = _exampleDartWebBoilerPlateFiles.map(function(fn){
|
||||
return path.join(EXAMPLES_PATH, fn);
|
||||
});
|
||||
var dartExampleWebPaths = getDartExampleWebPaths(EXAMPLES_PATH);
|
||||
|
||||
return copyFiles(sourceFiles, examplePaths)
|
||||
// Make boilerplate files read-only to avoid that they be edited by mistake.
|
||||
var destFileMode = '444';
|
||||
return copyFiles(sourceFiles, examplePaths, destFileMode)
|
||||
.then(function() {
|
||||
return copyFiles(dartWebSourceFiles, dartExampleWebPaths);
|
||||
return copyFiles(dartWebSourceFiles, dartExampleWebPaths, destFileMode);
|
||||
})
|
||||
// copy certain files from _examples/_protractor dir to each subdir that contains an e2e-spec file.
|
||||
.then(function() {
|
||||
|
@ -415,7 +428,7 @@ function copyExampleBoilerplate() {
|
|||
_exampleProtractorBoilerplateFiles
|
||||
.map(function(name) {return path.join(EXAMPLES_PROTRACTOR_PATH, name);});;
|
||||
var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH);
|
||||
return copyFiles(protractorSourceFiles, e2eSpecPaths);
|
||||
return copyFiles(protractorSourceFiles, e2eSpecPaths, destFileMode);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -789,16 +802,23 @@ function showHideExampleNodeModules(showOrHide) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Copies fileNames into destPaths, setting the mode of the
|
||||
// files at the destination as optional_destFileMode if given.
|
||||
// returns a promise
|
||||
function copyFiles(fileNames, destPaths) {
|
||||
function copyFiles(fileNames, destPaths, optional_destFileMode) {
|
||||
var copy = Q.denodeify(fsExtra.copy);
|
||||
var chmod = Q.denodeify(fsExtra.chmod);
|
||||
var copyPromises = [];
|
||||
destPaths.forEach(function(destPath) {
|
||||
fileNames.forEach(function(fileName) {
|
||||
var baseName = path.basename(fileName);
|
||||
var destName = path.join(destPath, baseName);
|
||||
var p = copy(fileName, destName, { clobber: true});
|
||||
if(optional_destFileMode !== undefined) {
|
||||
p = p.then(function () {
|
||||
return chmod(destName, optional_destFileMode);
|
||||
});
|
||||
}
|
||||
copyPromises.push(p);
|
||||
});
|
||||
});
|
||||
|
@ -841,7 +861,7 @@ function getTypingsPaths(basePath) {
|
|||
|
||||
function getExamplePaths(basePath, includeBase) {
|
||||
// includeBase defaults to false
|
||||
return getPaths(basePath, "example-config.json", includeBase)
|
||||
return getPaths(basePath, _exampleConfigFilename, includeBase)
|
||||
}
|
||||
|
||||
function getDartExampleWebPaths(basePath) {
|
||||
|
|
|
@ -235,7 +235,7 @@ script.
|
|||
|
||||
//- Returns truthy iff path is example project relative.
|
||||
- var isProjRelDir = function(path) {
|
||||
- return !path.match(/\/(js|ts|dart)(-snippets)?\//) && !path.endsWith('e2e-spec.js');
|
||||
- return !path.match(/\/(js|ts|dart)(-snippets)?\//) && !path.endsWith('e2e-spec.ts');
|
||||
- // Last conjunct handles case for shared project e2e test file like
|
||||
- // cb-component-communication/e2e-spec.js (is shared between ts & dart)
|
||||
- // TODO: generalize: compare start with getExampleName(); which needs to be fixed.
|
||||
|
|
|
@ -1,23 +1,17 @@
|
|||
# _exampleBoilerplateFiles
|
||||
.editorconfig
|
||||
.idea
|
||||
.vscode
|
||||
styles.css
|
||||
typings
|
||||
typings.json
|
||||
node_modules
|
||||
jspm_packages
|
||||
*.js.map
|
||||
package.json
|
||||
karma.conf.js
|
||||
karma-test-shim.js
|
||||
package.json
|
||||
*/**/styles.css
|
||||
systemjs.config.js
|
||||
tsconfig.json
|
||||
tslint.json
|
||||
typings.json
|
||||
wallaby.js
|
||||
npm-debug*.
|
||||
|
||||
protractor.config.js
|
||||
systemjs.config.js
|
||||
_test-output
|
||||
_temp
|
||||
**/ts/**/*.js
|
||||
**/ts-snippets/**/*.js
|
||||
*.d.ts
|
||||
|
|
|
@ -36,3 +36,4 @@ Thumbs.db
|
|||
!config/karma.conf.js
|
||||
!config/protractor.conf.js
|
||||
!src/typings.d.ts
|
||||
!src/tsconfig.json
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"build": "build:cli",
|
||||
"run": "http-server:cli"
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"declaration": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"noEmitOnError": true,
|
||||
"noImplicitAny": false,
|
||||
"outDir": "../dist/",
|
||||
"rootDir": ".",
|
||||
"sourceMap": true,
|
||||
"target": "es5",
|
||||
"inlineSources": true
|
||||
},
|
||||
|
||||
"files": [
|
||||
"main.ts",
|
||||
"typings.d.ts"
|
||||
]
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
"webdriver:update": "webdriver-manager update",
|
||||
"start:webpack": "webpack-dev-server --inline --progress --port 8080",
|
||||
"test:webpack": "karma start karma.webpack.conf.js",
|
||||
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail",
|
||||
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail",
|
||||
"build:cli": "ng build"
|
||||
},
|
||||
"keywords": [],
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
// Bundled (~40 requests):
|
||||
function packUmd(pkgName) {
|
||||
packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' };
|
||||
};
|
||||
}
|
||||
|
||||
// Most environments should use UMD; some (Karma) need the individual index files
|
||||
var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
|
||||
|
@ -52,7 +52,7 @@
|
|||
var config = {
|
||||
map: map,
|
||||
packages: packages
|
||||
}
|
||||
};
|
||||
|
||||
System.config(config);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
// Bundled (~40 requests):
|
||||
function packUmd(pkgName) {
|
||||
packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' };
|
||||
};
|
||||
}
|
||||
|
||||
// Most environments should use UMD; some (Karma) need the individual index files
|
||||
var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
|
||||
|
@ -51,7 +51,7 @@
|
|||
var config = {
|
||||
map: map,
|
||||
packages: packages
|
||||
}
|
||||
};
|
||||
|
||||
System.config(config);
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
},
|
||||
map: map,
|
||||
packages: packages
|
||||
}
|
||||
};
|
||||
|
||||
System.config(config);
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/// <reference path="../_protractor/e2e.d.ts" />
|
||||
describe('Tutorial part 1', () => {
|
||||
|
||||
let expectedH1 = 'Tour of Heroes';
|
||||
let expectedTitle = `Angular 2 ${expectedH1}`;
|
||||
let hero = { id: 1, name: 'Windstorm' };
|
||||
let expectedH2 = `${hero.name} details!`;
|
||||
|
||||
beforeEach(() => {
|
||||
return browser.get('');
|
||||
});
|
||||
|
||||
it(`should have title '${expectedTitle}'`, () => {
|
||||
expect(browser.getTitle()).toEqual(expectedTitle);
|
||||
});
|
||||
|
||||
it(`should have '${expectedH2}'`, () => {
|
||||
let text = element(by.css('h2')).getText();
|
||||
expect(text).toEqual(expectedH2);
|
||||
});
|
||||
|
||||
it(`should have input name '${hero.name}'`, () => {
|
||||
let name = element(by.css('input')).getAttribute('value');
|
||||
expect(name).toEqual(hero.name);
|
||||
});
|
||||
});
|
|
@ -37,10 +37,3 @@ export class AppComponent {
|
|||
hero = 'Windstorm';
|
||||
}
|
||||
// #enddocregion app-component-1
|
||||
|
||||
// #docregion hero-property-1
|
||||
hero: Hero = {
|
||||
id: 1,
|
||||
name: 'Windstorm'
|
||||
};
|
||||
// #enddocregion hero-property-1
|
||||
|
|
|
@ -22,10 +22,11 @@ export class Hero {
|
|||
})
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
// #docregion hero-property-1
|
||||
hero: Hero = {
|
||||
id: 1,
|
||||
name: 'Windstorm'
|
||||
};
|
||||
// #enddocregion hero-property-1
|
||||
}
|
||||
|
||||
// #enddocregion pt1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// #docregion pt2
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
export class Hero {
|
||||
|
@ -42,7 +42,7 @@ const HEROES: Hero[] = [
|
|||
</div>
|
||||
</div>
|
||||
`,
|
||||
// #docregion styles-1
|
||||
// #docregion styles
|
||||
styles: [`
|
||||
.selected {
|
||||
background-color: #CFD8DC !important;
|
||||
|
@ -92,18 +92,16 @@ const HEROES: Hero[] = [
|
|||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
`]
|
||||
// #enddocregion styles-1
|
||||
// #enddocregion styles
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
heroes = HEROES;
|
||||
// #docregion selected-hero-1
|
||||
// #docregion selected-hero
|
||||
selectedHero: Hero;
|
||||
// #enddocregion selected-hero-1
|
||||
// #enddocregion selected-hero
|
||||
|
||||
// #docregion on-select-1
|
||||
// #docregion on-select
|
||||
onSelect(hero: Hero) { this.selectedHero = hero; }
|
||||
// #enddocregion on-select-1
|
||||
// #enddocregion on-select
|
||||
}
|
||||
|
||||
// #enddocregion pt2
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// #docregion pt1
|
||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
bootstrap(AppComponent);
|
||||
// #enddocregion pt1
|
||||
|
|
|
@ -61,5 +61,3 @@ export class AppComponent implements OnInit {
|
|||
onSelect(hero: Hero) { this.selectedHero = hero; }
|
||||
// #docregion on-init
|
||||
}
|
||||
// #enddocregion on-init
|
||||
// #enddocregion
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Hero } from './hero';
|
|||
selector: 'my-hero-detail',
|
||||
template: `
|
||||
<div *ngIf="hero">
|
||||
<h2>{{hero.name}} details</h2>
|
||||
<h2>{{hero.name}} details!</h2>
|
||||
<div>
|
||||
<label>id: </label>{{hero.id}}
|
||||
</div>
|
||||
|
|
|
@ -6,18 +6,14 @@ import { Injectable } from '@angular/core';
|
|||
// #enddocregion empty-class
|
||||
import { HEROES } from './mock-heroes';
|
||||
|
||||
// #docregion empty-class
|
||||
// #docregion getHeroes-stub
|
||||
// #docregion empty-class, getHeroes-stub
|
||||
@Injectable()
|
||||
export class HeroService {
|
||||
// #enddocregion empty-class
|
||||
// #enddocregion empty-class
|
||||
getHeroes() {
|
||||
// #enddocregion getHeroes-stub
|
||||
// #enddocregion getHeroes-stub
|
||||
return HEROES;
|
||||
// #docregion getHeroes-stub
|
||||
// #docregion getHeroes-stub
|
||||
}
|
||||
// #docregion empty-class
|
||||
// #docregion empty-class
|
||||
}
|
||||
// #enddocregion getHeroes-stub
|
||||
// #enddocregion empty-class
|
||||
// #enddocregion
|
||||
|
|
|
@ -12,8 +12,8 @@ export class HeroService {
|
|||
getHeroes() {
|
||||
return Promise.resolve(HEROES);
|
||||
}
|
||||
// #enddocregion get-heroes
|
||||
// #enddocregion just-get-heroes
|
||||
// #enddocregion get-heroes, just-get-heroes
|
||||
// #enddocregion
|
||||
// See the "Take it slow" appendix
|
||||
// #docregion get-heroes-slowly
|
||||
getHeroesSlowly() {
|
||||
|
@ -22,7 +22,6 @@ export class HeroService {
|
|||
);
|
||||
}
|
||||
// #enddocregion get-heroes-slowly
|
||||
// #docregion
|
||||
// #docregion just-get-heroes
|
||||
}
|
||||
// #enddocregion just-get-heroes
|
||||
// #enddocregion
|
||||
|
|
|
@ -13,4 +13,3 @@ export var HEROES: Hero[] = [
|
|||
{id: 19, name: 'Magma'},
|
||||
{id: 20, name: 'Tornado'}
|
||||
];
|
||||
// #enddocregion
|
||||
|
|
|
@ -11,7 +11,6 @@ import { HeroesComponent } from './heroes.component';
|
|||
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
|
||||
|
||||
// #docregion
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `
|
||||
|
@ -20,13 +19,12 @@ import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/route
|
|||
`,
|
||||
directives: [HeroesComponent],
|
||||
providers: [
|
||||
// #enddocregion
|
||||
// #enddocregion
|
||||
ROUTER_PROVIDERS,
|
||||
// #docregion
|
||||
// #docregion
|
||||
HeroService
|
||||
]
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
}
|
||||
// #enddocregion
|
||||
|
|
|
@ -10,14 +10,14 @@ import { HeroesComponent } from './heroes.component';
|
|||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
// #docregion template
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
// #enddocregion template
|
||||
// #docregion directives-and-providers
|
||||
// #enddocregion template
|
||||
// #docregion directives-and-providers
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
providers: [
|
||||
ROUTER_PROVIDERS,
|
||||
|
@ -37,4 +37,3 @@ import { HeroesComponent } from './heroes.component';
|
|||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
}
|
||||
// #enddocregion
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* #docplaster */
|
||||
/* #docregion css */
|
||||
/* #docregion */
|
||||
h1 {
|
||||
font-size: 1.2em;
|
||||
color: #999;
|
||||
|
@ -28,4 +27,3 @@ nav a:hover {
|
|||
nav a.router-link-active {
|
||||
color: #039be5;
|
||||
}
|
||||
/* #enddocregion css */
|
||||
|
|
|
@ -12,7 +12,7 @@ import { HeroService } from './hero.service';
|
|||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
// #docregion template
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<nav>
|
||||
|
@ -21,10 +21,10 @@ import { HeroService } from './hero.service';
|
|||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
// #enddocregion template
|
||||
// #docregion style-urls
|
||||
// #enddocregion template
|
||||
// #docregion style-urls
|
||||
styleUrls: ['app/app.component.css'],
|
||||
// #enddocregion style-urls
|
||||
// #enddocregion style-urls
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
providers: [
|
||||
ROUTER_PROVIDERS,
|
||||
|
@ -32,21 +32,21 @@ import { HeroService } from './hero.service';
|
|||
]
|
||||
})
|
||||
@RouteConfig([
|
||||
// #docregion dashboard-route
|
||||
// #docregion dashboard-route
|
||||
{
|
||||
path: '/dashboard',
|
||||
name: 'Dashboard',
|
||||
component: DashboardComponent,
|
||||
useAsDefault: true
|
||||
},
|
||||
// #enddocregion dashboard-route
|
||||
// #docregion hero-detail-route
|
||||
// #enddocregion dashboard-route
|
||||
// #docregion hero-detail-route
|
||||
{
|
||||
path: '/detail/:id',
|
||||
name: 'HeroDetail',
|
||||
component: HeroDetailComponent
|
||||
},
|
||||
// #enddocregion hero-detail-route
|
||||
// #enddocregion hero-detail-route
|
||||
{
|
||||
path: '/heroes',
|
||||
name: 'Heroes',
|
||||
|
@ -56,4 +56,3 @@ import { HeroService } from './hero.service';
|
|||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
}
|
||||
// #enddocregion
|
||||
|
|
|
@ -24,4 +24,3 @@ export class DashboardComponent implements OnInit {
|
|||
|
||||
gotoDetail() { /* not implemented yet */}
|
||||
}
|
||||
// #enddocregion component
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* #docplaster */
|
||||
/* #docregion */
|
||||
[class*='col-'] {
|
||||
float: left;
|
||||
|
@ -60,4 +59,3 @@ h4 {
|
|||
min-width: 60px;
|
||||
}
|
||||
}
|
||||
/* #enddocregion */
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<!-- #docregion -->
|
||||
<h3>Top Heroes</h3>
|
||||
<div class="grid grid-pad">
|
||||
<!-- #docregion click -->
|
||||
<!-- #docregion click -->
|
||||
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1-4">
|
||||
<!-- #enddocregion click -->
|
||||
<!-- #enddocregion click -->
|
||||
<div class="module hero">
|
||||
<h4>{{hero.name}}</h4>
|
||||
</div>
|
||||
|
|
|
@ -22,12 +22,12 @@ export class DashboardComponent implements OnInit {
|
|||
|
||||
heroes: Hero[] = [];
|
||||
|
||||
// #docregion ctor
|
||||
// #docregion ctor
|
||||
constructor(
|
||||
private router: Router,
|
||||
private heroService: HeroService) {
|
||||
}
|
||||
// #enddocregion ctor
|
||||
// #enddocregion ctor
|
||||
|
||||
ngOnInit() {
|
||||
this.heroService.getHeroes()
|
||||
|
@ -41,4 +41,3 @@ export class DashboardComponent implements OnInit {
|
|||
}
|
||||
// #enddocregion goto-detail
|
||||
}
|
||||
// #enddocregion
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion v2
|
||||
// #docregion import-oninit
|
||||
// #docregion import-oninit, v2
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
// #enddocregion import-oninit
|
||||
// #docregion import-route-params
|
||||
|
@ -18,25 +17,24 @@ import { HeroService } from './hero.service';
|
|||
selector: 'my-hero-detail',
|
||||
// #docregion template-url
|
||||
templateUrl: 'app/hero-detail.component.html',
|
||||
// #enddocregion template-url
|
||||
// #enddocregion v2
|
||||
// #enddocregion template-url, v2
|
||||
styleUrls: ['app/hero-detail.component.css']
|
||||
// #docregion v2
|
||||
// #docregion v2
|
||||
})
|
||||
// #enddocregion extract-template
|
||||
// #docregion implement
|
||||
export class HeroDetailComponent implements OnInit {
|
||||
// #enddocregion implement
|
||||
// #enddocregion implement
|
||||
hero: Hero;
|
||||
|
||||
// #docregion ctor
|
||||
// #docregion ctor
|
||||
constructor(
|
||||
private heroService: HeroService,
|
||||
private routeParams: RouteParams) {
|
||||
}
|
||||
// #enddocregion ctor
|
||||
// #enddocregion ctor
|
||||
|
||||
// #docregion ng-oninit
|
||||
// #docregion ng-oninit
|
||||
ngOnInit() {
|
||||
// #docregion get-id
|
||||
let id = +this.routeParams.get('id');
|
||||
|
@ -44,13 +42,11 @@ export class HeroDetailComponent implements OnInit {
|
|||
this.heroService.getHero(id)
|
||||
.then(hero => this.hero = hero);
|
||||
}
|
||||
// #enddocregion ng-oninit
|
||||
// #enddocregion ng-oninit
|
||||
|
||||
// #docregion go-back
|
||||
// #docregion go-back
|
||||
goBack() {
|
||||
window.history.back();
|
||||
}
|
||||
// #enddocregion go-back
|
||||
}
|
||||
// #enddocregion v2
|
||||
// #enddocregion
|
||||
|
|
|
@ -24,4 +24,3 @@ export class HeroService {
|
|||
}
|
||||
// #enddocregion get-hero
|
||||
}
|
||||
// #enddocregion
|
||||
|
|
|
@ -17,5 +17,3 @@
|
|||
</h2>
|
||||
<button (click)="gotoDetail()">View Details</button>
|
||||
</div>
|
||||
<!-- #enddocregion mini-detail -->
|
||||
<!-- #enddocregion -->
|
||||
|
|
|
@ -6,21 +6,18 @@ import { Router } from '@angular/router-deprecated';
|
|||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
// #docregion metadata
|
||||
// #docregion heroes-component-renaming
|
||||
// #docregion heroes-component-renaming, metadata
|
||||
@Component({
|
||||
selector: 'my-heroes',
|
||||
// #enddocregion heroes-component-renaming
|
||||
// #enddocregion heroes-component-renaming
|
||||
templateUrl: 'app/heroes.component.html',
|
||||
styleUrls: ['app/heroes.component.css']
|
||||
// #docregion heroes-component-renaming
|
||||
// #docregion heroes-component-renaming
|
||||
})
|
||||
// #enddocregion heroes-component-renaming
|
||||
// #enddocregion metadata
|
||||
// #docregion class
|
||||
// #docregion heroes-component-renaming
|
||||
// #enddocregion heroes-component-renaming, metadata
|
||||
// #docregion class, heroes-component-renaming
|
||||
export class HeroesComponent implements OnInit {
|
||||
// #enddocregion heroes-component-renaming
|
||||
// #enddocregion heroes-component-renaming
|
||||
heroes: Hero[];
|
||||
selectedHero: Hero;
|
||||
|
||||
|
@ -41,8 +38,5 @@ export class HeroesComponent implements OnInit {
|
|||
gotoDetail() {
|
||||
this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
|
||||
}
|
||||
// #docregion heroes-component-renaming
|
||||
// #docregion heroes-component-renaming
|
||||
}
|
||||
// #enddocregion heroes-component-renaming
|
||||
// #enddocregion class
|
||||
// #enddocregion
|
||||
|
|
|
@ -13,4 +13,3 @@ export var HEROES: Hero[] = [
|
|||
{id: 19, name: 'Magma'},
|
||||
{id: 20, name: 'Tornado'}
|
||||
];
|
||||
// #enddocregion
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- #docregion head -->
|
||||
<!-- #docregion base-href -->
|
||||
<!-- #docregion base-href -->
|
||||
<head>
|
||||
<base href="/">
|
||||
<!-- #enddocregion base-href -->
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
/* #docregion */
|
||||
h2 {
|
||||
/* #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;
|
||||
|
@ -11,23 +17,7 @@ body, input[text], button {
|
|||
color: #888;
|
||||
font-family: Cambria, Georgia;
|
||||
}
|
||||
button {
|
||||
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: #aaa;
|
||||
cursor: auto;
|
||||
}
|
||||
/* . . . */
|
||||
/* everywhere else */
|
||||
* {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion, variables-imports
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
|
||||
// #enddocregion variables-imports
|
||||
import { RouteParams } from '@angular/router-deprecated';
|
||||
|
||||
import { Hero } from './hero';
|
||||
|
@ -11,11 +13,13 @@ import { HeroService } from './hero.service';
|
|||
templateUrl: 'app/hero-detail.component.html',
|
||||
styleUrls: ['app/hero-detail.component.css']
|
||||
})
|
||||
// #docregion variables-imports
|
||||
export class HeroDetailComponent implements OnInit {
|
||||
@Input() hero: Hero;
|
||||
@Output() close = new EventEmitter();
|
||||
error: any;
|
||||
navigated = false; // true if navigated here
|
||||
// #enddocregion variables-imports
|
||||
|
||||
constructor(
|
||||
private heroService: HeroService,
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/// <reference path="../_protractor/e2e.d.ts" />
|
||||
describe('QuickStart E2E Tests', function () {
|
||||
|
||||
let expectedMsg = 'Hello from Angular 2 App with Webpack';
|
||||
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it(`should display: ${expectedMsg}`, function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual(expectedMsg);
|
||||
});
|
||||
|
||||
it('should display an image', function () {
|
||||
expect(element(by.css('img')).isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"build": "build:webpack",
|
||||
"run": "http-server:cli"
|
||||
}
|
|
@ -126,11 +126,10 @@ a(id='toc')
|
|||
|
||||
我们遵循[单一职责原则](https:\/\/en.wikipedia.org/wiki/Single_responsibility_principle)来创建的所有组件、服务和其它标志等。这样能帮助我们把应用程序弄的干净整洁,易于阅读、维护和测试。
|
||||
|
||||
### Rule of One
|
||||
### 单一法则
|
||||
<a id="01-01"></a>
|
||||
#### Style 01-01
|
||||
#### 风格 01-01
|
||||
### <a id="01-01"></a>Rule of One
|
||||
### <a id="01-01"></a>单一法则
|
||||
#### <a href="#01-01">Style 01-01</a>
|
||||
#### <a href="#01-01">风格 01-01</a>
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** define one thing (e.g. service or component) per file.
|
||||
|
@ -202,12 +201,13 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Small Functions
|
||||
### 小函数
|
||||
<a id="01-02"></a>
|
||||
#### Style 01-02
|
||||
#### 风格01-02
|
||||
.s-rule.do
|
||||
### <a id="01-02"></a>Small Functions
|
||||
### <a id="01-02"></a>小函数
|
||||
|
||||
#### <a href="#01-02">Style 01-02</a>
|
||||
#### <a href="#01-02">风格01-02</a>
|
||||
|
||||
:marked
|
||||
**Do** define small functions
|
||||
|
||||
|
@ -263,11 +263,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### General Naming Guidelines
|
||||
### 总体命名指导原则
|
||||
<a id="02-01"></a>
|
||||
#### Style 02-01
|
||||
#### 风格02-01
|
||||
### <a id="02-01"></a>General Naming Guidelines
|
||||
### <a id="02-01"></a>总体命名知道原则
|
||||
#### <a href="#02-01">Style 02-01</a>
|
||||
#### <a href="#02-01">风格02-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -307,11 +306,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Separate File Names with Dots and Dashes
|
||||
### 使用点和横杠来分隔文件名字
|
||||
<a id="02-02"></a>
|
||||
#### Style 02-02
|
||||
#### 风格02-02
|
||||
### <a id="02-02"></a>Separate File Names with Dots and Dashes
|
||||
### <a id="02-02"></a>使用点和横杠来分隔文件名
|
||||
#### <a href="#02-02">Style 02-02</a>
|
||||
#### <a href="#02-02">风格02-02</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -376,11 +374,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Components and Directives
|
||||
### 组件和指令命名
|
||||
<a id="02-03"></a>
|
||||
#### Style 02-03
|
||||
#### 风格02-03
|
||||
### <a id="02-03"></a>Components and Directives
|
||||
### <a id="02-03"></a>组件与指令命名
|
||||
#### <a href="#02-03">Style 02-03</a>
|
||||
#### <a href="#02-03">风格02-03</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -478,11 +475,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Service Names
|
||||
### 服务名
|
||||
<a id="02-04"></a>
|
||||
#### Style 02-04
|
||||
#### 风格02-04
|
||||
### <a id="02-04"></a>Service Names
|
||||
### <a id="02-04"></a>服务名
|
||||
#### <a href="#02-04">Style 02-04</a>
|
||||
#### <a href="#02-04">风格02-04</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -563,11 +559,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Bootstrapping
|
||||
### 引导程序
|
||||
<a id="02-05"></a>
|
||||
#### Style 02-05
|
||||
#### 风格02-05
|
||||
### <a id="02-05"></a>Bootstrapping
|
||||
### <a id="02-05"></a>引导
|
||||
#### <a href="#02-05">Style 02-05</a>
|
||||
#### <a href="#02-05">风格02-05</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -600,11 +595,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Directive Selectors
|
||||
### 指令的选择器
|
||||
<a id="02-06"></a>
|
||||
#### Style 02-06
|
||||
#### 风格02-06
|
||||
### <a id="02-06"></a>Directive Selectors
|
||||
### <a id="02-06"></a>指令的选择器
|
||||
#### <a href="#02-06">Style 02-06</a>
|
||||
#### <a href="#02-06">风格02-06</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -631,11 +625,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Custom Prefix for Components
|
||||
### 为组件自定义前缀
|
||||
<a id="02-07"></a>
|
||||
#### Style 02-07
|
||||
#### 风格02-07
|
||||
### <a id="02-07"></a>Custom Prefix for Components
|
||||
### <a id="02-07"></a>为组件自定义前缀
|
||||
#### <a href="#02-07">Style 02-07</a>
|
||||
#### <a href="#02-07">风格02-07</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -680,11 +673,10 @@ a(href="#toc") 回到顶部
|
|||
:marked
|
||||
|
||||
:marked
|
||||
### Custom Prefix for Directives
|
||||
### 为指令添加自定义前缀
|
||||
<a id="02-08"></a>
|
||||
#### Style 02-08
|
||||
#### 风格02-08
|
||||
### <a id="02-08"></a>Custom Prefix for Directives
|
||||
### <a id="02-08"></a>为指令添加自定义前缀
|
||||
#### <a href="#02-08">Style 02-08</a>
|
||||
#### <a href="#02-08">风格02-08</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -716,11 +708,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Pipe Names
|
||||
### 管道名
|
||||
<a id="02-09"></a>
|
||||
#### Style 02-09
|
||||
#### 风格02-09
|
||||
### <a id="02-09"></a>Pipe Names
|
||||
### <a id="02-09"></a>管道名
|
||||
#### <a href="#02-09">Style 02-09</a>
|
||||
#### <a href="#02-09">风格02-09</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -769,11 +760,9 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Unit Test File Names
|
||||
### 单元测试文件命名
|
||||
<a id="02-10"></a>
|
||||
#### Style 02-10
|
||||
#### 风格02-10
|
||||
### <a id="02-10"></a>Unit Test File Names
|
||||
### <a id="02-10"></a>单元测试文件名
|
||||
#### <a href="#02-10">风格02-10</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -856,11 +845,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### End to End Test File Names
|
||||
### 端到端测试文件命名
|
||||
<a id="02-11"></a>
|
||||
#### Style 02-11
|
||||
#### 风格02-11
|
||||
### <a id="02-11"></a>End to End Test File Names
|
||||
### <a id="02-11"></a>端到端测试文件名
|
||||
#### <a href="#02-11">Style 02-11</a>
|
||||
#### <a href="#02-11">风格02-11</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -921,11 +909,8 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Classes
|
||||
### 类
|
||||
<a id="03-01"></a>
|
||||
#### Style 03-01
|
||||
#### 风格03-01
|
||||
### <a id="03-01"></a>类
|
||||
#### <a href="#03-01">风格03-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -958,11 +943,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Constants
|
||||
### 常量
|
||||
<a id="03-02"></a>
|
||||
#### Style 03-02
|
||||
#### 风格03-02
|
||||
### <a id="03-02"></a>Constants
|
||||
### <a id="03-02"></a>常量
|
||||
#### <a href="#03-02">Style 03-02</a>
|
||||
#### <a href="#03-02">风格03-02</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -995,11 +979,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Interfaces
|
||||
### 接口
|
||||
<a id="03-03"></a>
|
||||
#### Style 03-03
|
||||
#### 风格03-03
|
||||
### <a id="03-03"></a>Interfaces
|
||||
### <a id="03-03"></a>接口
|
||||
#### <a href="#03-03">Style 03-03</a>
|
||||
#### <a href="#03-03">风格03-03</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1032,11 +1015,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Properties and Methods
|
||||
### 属性和方法名
|
||||
<a id="03-04"></a>
|
||||
#### Style 03-04
|
||||
#### 风格03-04
|
||||
### <a id="03-04"></a>Properties and Methods
|
||||
### <a id="03-04"></a>属性和方法
|
||||
#### <a href="#03-04">Style 03-04</a>
|
||||
#### <a href="#03-04">样式03-04</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1081,11 +1063,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Import Destructuring Spacing
|
||||
### 导入语句解构表达式中的空格
|
||||
<a id="03-05"></a>
|
||||
#### Style 03-05
|
||||
#### 风格03-05
|
||||
### <a id="03-05"></a>Import Destructuring Spacing
|
||||
### <a id="03-05"></a>导入语句解构表达式中的空格
|
||||
#### <a href="#03-05">Style 03-05</a>
|
||||
#### <a href="#03-05">风格03-05</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1111,11 +1092,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Import Line Spacing
|
||||
### 导入语句中的空行
|
||||
<a id="03-06"></a>
|
||||
#### Style 03-06
|
||||
#### 风格03-06
|
||||
### <a id="03-06"></a>Import Line Spacing
|
||||
### <a id="03-06"></a>导入语句中的空行
|
||||
#### <a href="#03-06">Style 03-06</a>
|
||||
#### <a href="#03-06">风格03-06</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1179,11 +1159,9 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### LIFT
|
||||
### LIFT (定位`L`ocate、识别`I`dentity、平面化`F`lattest、尝试`T`ry遵循不重复自己DRY - Do Not Repeat Yourself约定)
|
||||
<a id="04-01"></a>
|
||||
#### Style 04-01
|
||||
#### 风格04-01
|
||||
### <a id="04-01"></a>LIFT
|
||||
#### <a href="#04-01">Style 04-01</a>
|
||||
#### <a href="#04-01">风格04-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1208,11 +1186,11 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Locate
|
||||
### 定位
|
||||
<a id="04-02"></a>
|
||||
#### Style 04-02
|
||||
#### 风格04-02
|
||||
### <a id="04-02"></a>Locate
|
||||
### <a id="04-02"></a>定位
|
||||
|
||||
#### <a href="#04-02">Style 04-02</a>
|
||||
#### <a href="#04-02">风格04-02</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1232,11 +1210,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Identify
|
||||
### 识别
|
||||
<a id="04-03"></a>
|
||||
#### Style 04-03
|
||||
#### 风格04-03
|
||||
### <a id="04-03"></a>Identify
|
||||
### <a id="04-03"></a>识别
|
||||
#### <a href="#04-03">Style 04-03</a>
|
||||
#### <a href="#04-03">风格04-03</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1275,11 +1252,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Flat
|
||||
### 平面化
|
||||
<a id="04-04"></a>
|
||||
#### Style 04-04
|
||||
#### 风格04-04
|
||||
### <a id="04-04"></a>Flat
|
||||
### <a id="04-04"></a>平面化
|
||||
#### <a href="#04-04">Style 04-04</a>
|
||||
#### <a href="#04-04">风格04-04</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1305,11 +1281,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### T-DRY (Try to be DRY)
|
||||
### T-DRY(尝试遵循不重复自己DRY的约定)
|
||||
<a id="04-05"></a>
|
||||
#### Style 04-05
|
||||
#### 风格04-05
|
||||
### <a id="04-05"></a>T-DRY (Try to be DRY)
|
||||
### <a id="04-05"></a>T-DRY (尝试遵循不重复自己DRY的约定)
|
||||
#### <a href="#04-05">Style 04-05</a>
|
||||
#### <a href="#04-05">风格04-05</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1335,11 +1310,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Overall Structural Guidelines
|
||||
### 总体结构指导原则
|
||||
<a id="04-06"></a>
|
||||
#### Style 04-06
|
||||
#### 风格04-06
|
||||
### <a id="04-06"></a>Overall Structural Guidelines
|
||||
### <a id="04-06"></a>总体结构指导原则
|
||||
#### <a href="#04-06">Style 04-06</a>
|
||||
#### <a href="#04-06">风格04-06</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1422,11 +1396,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Shared Folder
|
||||
### 共享目录
|
||||
<a id="04-07"></a>
|
||||
#### Style 04-07
|
||||
#### 风格04-07
|
||||
### <a id="04-07"></a>Shared Folder
|
||||
### <a id="04-07"></a>共享目录
|
||||
#### <a href="#04-07">Style 04-07</a>
|
||||
#### <a href="#04-07">风格04-07</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1495,11 +1468,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Folders-by-Feature Structure
|
||||
### 根据特性划分的目录结构
|
||||
<a id="04-08"></a>
|
||||
#### Style 04-08
|
||||
#### 风格04-08
|
||||
### <a id="04-08"></a>Folders-by-Feature Structure
|
||||
### <a id="04-08"></a>根据特性划分的目录结构
|
||||
#### <a href="#04-08">Style 04-08</a>
|
||||
#### <a href="#04-08">风格04-08</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1586,11 +1558,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Layout Components
|
||||
### 布局组件
|
||||
<a id="04-09"></a>
|
||||
#### Style 04-09
|
||||
#### 风格04-09
|
||||
### <a id="04-09"></a>Layout Components
|
||||
### <a id="04-09"></a>布局组件
|
||||
#### <a href="#04-09">Style 04-09</a>
|
||||
#### <a href="#04-09">风格04-09</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1650,11 +1621,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Create and Import Barrels
|
||||
### 新建和导入封装桶
|
||||
<a id="04-10"></a>
|
||||
#### Style 04-10
|
||||
#### 风格04-10
|
||||
### <a id="04-10"></a>Create and Import Barrels
|
||||
### <a id="04-10"></a>创建和导入封装桶
|
||||
#### <a href="#04-10">Style 04-10</a>
|
||||
#### <a href="#04-10">风格04-10</a>
|
||||
|
||||
.s-rule.consider
|
||||
:marked
|
||||
|
@ -1760,11 +1730,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Lazy Loaded Folders
|
||||
### 惰性加载目录
|
||||
<a id="04-11"></a>
|
||||
#### Style 04-11
|
||||
#### 风格04-11
|
||||
### <a id="04-11"></a>Lazy Loaded Folders
|
||||
### <a id="04-11"></a>惰性加载目录
|
||||
#### <a href="#04-11">Style 04-11</a>
|
||||
#### <a href="#04-11">风格04-11</a>
|
||||
A distinct application feature or workflow may be *lazy loaded* or *loaded on demand* rather than when the application starts.
|
||||
|
||||
一个独特的应用程序特性或者工作流可能被**惰性加载**或**按需加载**,而非在应用程序启动时就全部加载。
|
||||
|
@ -1788,11 +1757,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Prefix Lazy Loaded Folders with +
|
||||
### 为惰性加载目录名字加前缀+
|
||||
<a id="04-12"></a>
|
||||
#### Style 04-12
|
||||
#### 风格04-12
|
||||
### <a id="04-12"></a>Prefix Lazy Loaded Folders with +
|
||||
### <a id="04-12"></a>为惰性加载目录名字加前缀+
|
||||
#### <a href="#04-12">Style 04-12</a>
|
||||
#### <a href="#04-12">样式04-12</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1836,11 +1804,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Never Directly Import Lazy Loaded Folders
|
||||
### 决不直接导入惰性加载目录
|
||||
<a id="04-13"></a>
|
||||
#### Style 04-13
|
||||
#### 风格
|
||||
### <a id="04-13"></a>Never Directly Import Lazy Loaded Folders
|
||||
### <a id="04-13"></a>决不直接导入惰性加载目录
|
||||
#### <a href="#04-13">Style 04-13</a>
|
||||
#### <a href="#04-13">风格04-13</a>
|
||||
|
||||
.s-rule.avoid
|
||||
:marked
|
||||
|
@ -1863,11 +1830,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Lazy Loaded Folders May Import From a Parent
|
||||
### <a id="04-14"></a>Lazy Loaded Folders May Import From a Parent
|
||||
### 惰性加载目录可以导入父级
|
||||
<a id="04-14"></a>
|
||||
#### Style 04-14
|
||||
#### 风格04-14
|
||||
#### <a href="#04-14">Style 04-14</a>
|
||||
#### <a href="#04-14">样式04-14</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1891,11 +1857,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Use Component Router to Lazy Load
|
||||
### 使用组件路由器来惰性加载
|
||||
<a id="04-15"></a>
|
||||
#### Style 04-15
|
||||
#### 风格04-15
|
||||
### <a id="04-15"></a>Use Component Router to Lazy Load
|
||||
### <a id="04-15"></a>使用组件路由器来惰性加载
|
||||
#### <a href="#04-15">Style 04-15</a>
|
||||
#### <a href="#04-15">风格04-15</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1917,12 +1882,11 @@ a(href="#toc") 回到顶部
|
|||
.l-main-section
|
||||
:marked
|
||||
## Components
|
||||
## 组件
|
||||
### Components Selector Naming
|
||||
### 组件选择器命名
|
||||
<a id="05-02"></a>
|
||||
#### Style 05-02
|
||||
#### 风格05-02
|
||||
|
||||
### <a id="05-02"></a>Components Selector Naming
|
||||
### <a id="05-02"></a>组件选择器命名
|
||||
#### <a href="#05-02">Style 05-02</a>
|
||||
#### <a href="#05-02">风格05-02</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -1953,11 +1917,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Components as Elements
|
||||
### 将组件当做元素
|
||||
<a id="05-03"></a>
|
||||
#### Style 05-03
|
||||
#### 风格05-03
|
||||
### <a id="05-03"></a>Components as Elements
|
||||
### <a id="05-03"></a>把组件当做元素
|
||||
#### <a href="#05-03">Style 05-03</a>
|
||||
#### <a href="#05-03">风格05-03</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2003,11 +1966,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Extract Template and Styles to Their Own Files
|
||||
### 把模板和样式提取到它们自己的文件
|
||||
<a id="05-04"></a>
|
||||
#### Style 05-04
|
||||
#### 风格05-04
|
||||
### <a id="05-04"></a>Extract Template and Styles to Their Own Files
|
||||
### <a id="05-04"></a>把模板和样式提取到它们自己的文件
|
||||
#### <a href="#05-04">Style 05-04</a>
|
||||
#### <a href="#05-04">风格05-04</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2059,11 +2021,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Decorate Input and Output Properties Inline
|
||||
### 内联Input和Output属性装饰
|
||||
<a id="05-12"></a>
|
||||
#### Style 05-12
|
||||
#### 风格05-12
|
||||
### <a id="05-12"></a>Decorate Input and Output Properties Inline
|
||||
### <a id="05-12"></a>内联Input和Output属性装饰器
|
||||
#### <a href="#05-12">Style 05-12</a>
|
||||
#### <a href="#05-12">风格05-12</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2113,11 +2074,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Avoid Renaming Inputs and Outputs
|
||||
### 避免重命名输入和输出
|
||||
<a id="05-13"></a>
|
||||
#### Style 05-13
|
||||
#### 风格05-13
|
||||
### <a id="05-13"></a>Avoid Renaming Inputs and Outputs
|
||||
### <a id="05-13"></a>避免重命名输入和输出
|
||||
#### <a href="#05-13">Style 05-13</a>
|
||||
#### <a href="#05-13">风格05-13</a>
|
||||
|
||||
.s-rule.avoid
|
||||
:marked
|
||||
|
@ -2152,11 +2112,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Member Sequence
|
||||
### 成员顺序
|
||||
<a id="05-14"></a>
|
||||
#### Style 05-14
|
||||
#### 风格05-14
|
||||
### <a id="05-14"></a>Member Sequence
|
||||
### <a id="05-14"></a>成员顺序
|
||||
#### <a href="#05-14">Style 05-14</a>
|
||||
#### <a href="#05-14">风格05-14</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2188,12 +2147,11 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Put Logic in Services
|
||||
### 把逻辑放到服务里
|
||||
<a id="05-15"></a>
|
||||
#### Style 05-15
|
||||
#### 风格05-15
|
||||
|
||||
### <a id="05-15"></a>Put Logic in Services
|
||||
### <a id="05-15"></a>把逻辑放到服务里
|
||||
#### <a href="#05-14">Style 05-15</a>
|
||||
#### <a href="#05-14">风格05-15</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
**Do** limit logic in a component to only that required for the view. All other logic should be delegated to services.
|
||||
|
@ -2243,11 +2201,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Don't Prefix Output Properties
|
||||
### 不要给输出属性加前缀
|
||||
<a id="05-16"></a>
|
||||
#### Style 05-16
|
||||
#### 风格05-16
|
||||
### <a id="05-16"></a>Don't Prefix Output Properties
|
||||
### <a id="05-16"></a>不要给输出属性加前缀
|
||||
#### <a href="#05-16">Style 05-16</a>
|
||||
#### <a href="#05-16">风格05-16</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2293,11 +2250,9 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Put Presentation Logic in the Component Class
|
||||
### 把展示逻辑放到组件类里
|
||||
<a id="05-17"></a>
|
||||
#### Style 05-17
|
||||
#### 风格05-17
|
||||
### <a id="05-17"></a>把展示逻辑放到组件类里
|
||||
#### <a href="#05-17">Style 05-17</a>
|
||||
#### <a href="#05-17">风格05-17</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2339,11 +2294,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Use Directives to Enhance an Existing Element
|
||||
### 使用指令来加强已有元素
|
||||
<a id="06-01"></a>
|
||||
#### Style 06-01
|
||||
#### 风格06-01
|
||||
### <a id="06-01"></a>Use Directives to Enhance an Existing Element
|
||||
### <a id="06-01"></a>使用指令来加强已有元素
|
||||
#### <a href="#06-01">Style 06-01</a>
|
||||
#### <a href="#06-01">风格06-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2375,11 +2329,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Use HostListener and HostBinding Class Decorators
|
||||
### 使用HostListener和HostBinding类装饰器
|
||||
<a id="06-03"></a>
|
||||
#### Style 06-03
|
||||
#### 风格06-03
|
||||
### <a id="06-03"></a>Use HostListener and HostBinding Class Decorators
|
||||
### <a id="06-03"></a>使用HostListener和HostBinding类装饰器
|
||||
#### <a href="#06-03">Style 06-03</a>
|
||||
#### <a href="#06-03">风格06-03</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2414,11 +2367,10 @@ a(href="#toc") 回到顶部
|
|||
## Services
|
||||
## 服务
|
||||
|
||||
### Services are Singletons in Same Injector
|
||||
### 在同一个注入器内,服务是单例
|
||||
<a id="07-01"></a>
|
||||
#### Style 07-01
|
||||
#### 风格07-01
|
||||
### <a id="07-01"></a>Services are Singletons in Same Injector
|
||||
### <a id="07-01"></a>在同一个注入器内,服务是单例
|
||||
#### <a href="#07-01">Style 07-01</a>
|
||||
#### <a href="#07-01">风格07-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2447,11 +2399,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Single Responsibility
|
||||
### 单一职责
|
||||
<a id="07-02"></a>
|
||||
#### Style 07-02
|
||||
#### 风格07-02
|
||||
### <a id="07-02"></a>Single Responsibility
|
||||
### <a id="07-02"></a>单一职责
|
||||
#### <a href="#07-02">Style 07-02</a>
|
||||
#### <a href="#07-02">风格07-02</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2483,11 +2434,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Providing a Service
|
||||
### 服务的提供
|
||||
<a id="07-03"></a>
|
||||
#### Style 07-03
|
||||
#### 风格07-03
|
||||
### <a id="07-03"></a>Providing a Service
|
||||
### <a id="07-03"></a>提供一个服务
|
||||
#### <a href="#07-03">Style 07-03</a>
|
||||
#### <a href="#07-03">风格07-03</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2532,11 +2482,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Use the @Injectable() Class Decorator
|
||||
### 使用@Injectable()类装饰器
|
||||
<a id="07-04"></a>
|
||||
#### Style 07-04
|
||||
#### 风格07-04
|
||||
### <a id="07-04"></a>Use the @Injectable() Class Decorator
|
||||
### <a id="07-04"></a>使用@Injectable()类装饰器
|
||||
#### <a href="#07-04">Style 07-04</a>
|
||||
#### <a href="#07-04">风格07-04</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2571,11 +2520,10 @@ a(href="#toc") 回到顶部
|
|||
## Data Services
|
||||
## 数据服务
|
||||
|
||||
### Separate Data Calls
|
||||
### 分离数据调用
|
||||
<a id="08-01"></a>
|
||||
#### Style 08-01
|
||||
#### 风格08-01
|
||||
### <a id="08-01"></a>Separate Data Calls
|
||||
### <a id="08-01"></a>分离数据调用
|
||||
#### <a href="#08-01">Style 08-01</a>
|
||||
#### <a href="#08-01">风格08-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2625,11 +2573,10 @@ a(href="#toc") Back to top
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Implement Lifecycle Hooks Interfaces
|
||||
### 实现生命周期钩子的接口
|
||||
<a id="09-01"></a>
|
||||
#### Style 09-01
|
||||
#### 风格09-01
|
||||
### <a id="09-01"></a>Implement Lifecycle Hooks Interfaces
|
||||
### <a id="09-01"></a>实现生命周期钩子接口
|
||||
#### <a href="#09-01">Style 09-01</a>
|
||||
#### <a href="#09-01">风格09-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2667,11 +2614,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Component Router
|
||||
### 组件路由器
|
||||
<a id="10-01"></a>
|
||||
#### Style 10-01
|
||||
#### 风格10-01
|
||||
### <a id="10-01"></a>Component Router
|
||||
### <a id="10-01"></a>组件路由器
|
||||
#### <a href="#10-01">Style 10-01</a>
|
||||
#### <a href="#10-01">风格10-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2731,11 +2677,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### Codelyzer
|
||||
### Codelyzer
|
||||
<a id="A-01"></a>
|
||||
#### Style A-01
|
||||
#### 风格A-01
|
||||
### <a id="A-01"></a>Codelyzer
|
||||
### <a id="A-01"></a>Codelyzer
|
||||
#### <a href="#A-01">Style A-01</a>
|
||||
#### <a href="#A-01">风格A-01</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
@ -2755,11 +2700,10 @@ a(href="#toc") 回到顶部
|
|||
|
||||
.l-main-section
|
||||
:marked
|
||||
### File Templates and Snippets
|
||||
### 文件模板和代码片段
|
||||
<a id="A-02"></a>
|
||||
#### Style A-02
|
||||
#### 风格A-02
|
||||
### <a id="A-02"></a>File Templates and Snippets
|
||||
### <a id="A-02"></a>文档模板和代码片段
|
||||
#### <a href="#A-02">Style A-02</a>
|
||||
#### <a href="#A-02">风格A-02</a>
|
||||
|
||||
.s-rule.do
|
||||
:marked
|
||||
|
|
|
@ -117,7 +117,7 @@ code-example(language="bash").
|
|||
现在,有了一个`Hero`类,我们就要把组件`hero`属性的类型换成`Hero`了。
|
||||
然后以`1`为id、以“Windstorm”为名字,初始化它。
|
||||
|
||||
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'hero-property-1', 'app.component.ts (hero属性)')(format=".")
|
||||
+makeExample('toh-1/ts/app/app.component.ts', 'hero-property-1', 'app.component.ts (hero property)')(format=".")
|
||||
|
||||
:marked
|
||||
Because we changed the hero from a string to an object,
|
||||
|
|
|
@ -71,7 +71,7 @@ code-example(language="bash").
|
|||
|
||||
我们先在`app.component.ts`的底部创建一个由十位英雄组成的数组。
|
||||
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'hero-array', 'app.component.ts (英雄数组)')
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'hero-array', 'app.component.ts (hero array)')
|
||||
|
||||
:marked
|
||||
The `HEROES` array is of type `Hero`, the class defined in part one,
|
||||
|
@ -84,11 +84,11 @@ code-example(language="bash").
|
|||
|
||||
### Exposing heroes
|
||||
### 导出英雄们
|
||||
Let’s create a property in `AppComponent` that exposes the heroes for binding.
|
||||
Let’s create a public property in `AppComponent` that exposes the heroes for binding.
|
||||
|
||||
我们在`AppComponent`上创建一个属性,用来暴露这些英雄,以供绑定。
|
||||
我们在`AppComponent`上创建一个公开属性,用来暴露这些英雄,以供绑定。
|
||||
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'hero-array-1', 'app.component.ts (英雄数组属性)')
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'hero-array-1', 'app.component.ts (hero array property)')
|
||||
|
||||
:marked
|
||||
We did not have to define the `heroes` type. TypeScript can infer it from the `HEROES` array.
|
||||
|
@ -113,7 +113,7 @@ code-example(language="bash").
|
|||
我们的组件有了`heroes`属性,我们再到模板中创建一个无序列表来显示他们。
|
||||
我们将在标题和英雄详情之间,插入下面这段HTML代码。
|
||||
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-template-1', 'app.component.ts (英雄模板)')
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-template-1', 'app.component.ts (heroes template)')
|
||||
|
||||
:marked
|
||||
Now we have a template that we can fill with our heroes.
|
||||
|
@ -160,7 +160,7 @@ code-example(language="bash").
|
|||
|
||||
引号中赋值给`ngFor`的那段儿文本表示“*从`heroes`数组中取出每个英雄,存入一个局部的`hero`变量,并让它在相应的模板实例中可用*”。
|
||||
|
||||
The `let` keyword before "hero" identifies the `hero` as a template input variable.
|
||||
The `let` keyword before "hero" identifies `hero` as a template input variable.
|
||||
We can reference this variable within the template to access a hero’s properties.
|
||||
|
||||
`hero`前的`let`关键字表示`hero`是一个模板输入变量。
|
||||
|
@ -199,13 +199,16 @@ code-example(language="bash").
|
|||
|
||||
要想给我们的组件添加一些样式,请把`@Component`装饰器的`styles`属性设置为下列CSS类:
|
||||
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'styles-1', 'app.component.ts (添加样式)')
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'styles', 'app.component.ts (styles)')(format=".")
|
||||
|
||||
:marked
|
||||
Notice that we again use the back-tick notation for multi-line strings.
|
||||
|
||||
注意,我们又使用了反引号语法来书写多行字符串。
|
||||
|
||||
That's a lot of styles! We can put them inline as shown here, or we can move them out to their own file which will make it easier to code our component.
|
||||
We'll do this in a later chapter. For now let's keep rolling.
|
||||
|
||||
When we assign styles to a component they are scoped to that specific component.
|
||||
Our styles will only apply to our `AppComponent` and won't "leak" to the outer HTML.
|
||||
|
||||
|
@ -216,14 +219,7 @@ code-example(language="bash").
|
|||
|
||||
用于显示英雄们的这个模板看起来像这样:
|
||||
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-styled', 'app.component.ts (带样式的英雄们)')
|
||||
|
||||
:marked
|
||||
That's a lot of styles! We can put them inline as shown here, or we can move them out to their own file which will make it easier to code our component.
|
||||
We'll do this in a later chapter. For now let's keep rolling.
|
||||
|
||||
样式有很多种写法!我们可以像这里一样内联在代码中,也可以把它们移出去,放到各自的文件中,以便给组件编码时更容易。
|
||||
等到后面的章节中我们肯定会这么干,但现在,还是保持现在的节奏吧。
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'heroes-styled', 'app.component.ts (styled heroes)')
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
|
@ -251,7 +247,7 @@ code-example(language="bash").
|
|||
|
||||
我们往`<li>`元素上插入一句Angular事件绑定代码,绑定到它的click事件。
|
||||
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-click', 'app.component.ts (捕获click事件)')
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-click', 'app.component.ts (template excerpt)')
|
||||
|
||||
:marked
|
||||
Focus on the event binding
|
||||
|
@ -305,7 +301,7 @@ code-example(language="bash").
|
|||
在`AppComponent`上,我们不再需要一个固定的`hero`属性。
|
||||
那就直接把它改为`selectedHero`属性。
|
||||
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'selected-hero-1', 'app.component.ts (selectedHero)')
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'selected-hero', 'app.component.ts (selectedHero)')
|
||||
|
||||
:marked
|
||||
We’ve decided that none of the heroes should be selected before the user picks a hero so
|
||||
|
@ -316,7 +312,8 @@ code-example(language="bash").
|
|||
Now **add an `onSelect` method** that sets the `selectedHero` property to the `hero` the user clicked.
|
||||
|
||||
现在,**添加一个`onSelect`方法**,以便在用户点击一个英雄的时候,把它赋给`selectedHero`属性。
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'on-select-1', 'app.component.ts (onSelect)')
|
||||
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'on-select', 'app.component.ts (onSelect)')
|
||||
|
||||
:marked
|
||||
We will be showing the selected hero's details in our template.
|
||||
|
@ -326,7 +323,7 @@ code-example(language="bash").
|
|||
我们将把所选英雄的详细信息显示在模板中。目前,它仍然引用的是以前的`hero`属性。
|
||||
我们这就修改模板,让它绑定到新的`selectedHero`属性上去。
|
||||
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-details', 'app.component.ts (绑定到selectedHero的名字)')
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'selectedHero-details', 'app.component.ts (template excerpt)')
|
||||
:marked
|
||||
### Hide the empty detail with ngIf
|
||||
### 利用ngIf隐藏空的详情
|
||||
|
@ -428,19 +425,20 @@ code-example(language="bash").
|
|||
|
||||
关键是CSS类的名字:`selected`。当两位英雄一致时,它为`true`,否则为`false`。
|
||||
也就是说:“*当两位英雄匹配时,应用上`selected`类,否则不应用*”。
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-1', 'app.component.ts (设置CSS类)')(format=".")
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-1', 'app.component.ts (setting the CSS class)')(format=".")
|
||||
:marked
|
||||
Notice in the template that the `class.selected` is surrounded in square brackets (`[]`).
|
||||
This is the syntax for a Property Binding, a binding in which data flows one way
|
||||
This is the syntax for a **property binding**, a binding in which data flows one way
|
||||
from the data source (the expression `hero === selectedHero`) to a property of `class`.
|
||||
|
||||
注意,模板中的`class.selected`是括在一对方括号中的。
|
||||
这就是“属性绑定”的语法,一种从数据源(即`hero === selectedHero`表达式)到`class`属性的单向数据流。
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-2', 'app.component.ts (Styling each hero)')(format=".")
|
||||
|
||||
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'class-selected-2', 'app.component.ts (styling each hero)')(format=".")
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
Learn more about [Property Binding](../guide/template-syntax.html#property-binding)
|
||||
Learn more about [property bindings](../guide/template-syntax.html#property-binding)
|
||||
in the Template Syntax chapter.
|
||||
|
||||
学习关于[属性绑定](../guide/template-syntax.html#property-binding)
|
||||
|
@ -464,7 +462,7 @@ code-example(language="bash").
|
|||
|
||||
完整的`app.component.ts`文件如下:
|
||||
|
||||
+makeExample('toh-2/ts/app/app.component.ts', 'pt2', 'app.component.ts')
|
||||
+makeExample('toh-2/ts/app/app.component.ts', '', 'app.component.ts')
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
|
|
|
@ -41,7 +41,7 @@ p 运行这部分的#[+liveExampleLink2('在线例子', 'toh-3')]。
|
|||
|
||||
我们要启动TypeScript编译器,它会监视文件变更,并启动开发服务器。只要敲:
|
||||
|
||||
code-example(format="." language="bash").
|
||||
code-example(language="bash").
|
||||
npm start
|
||||
|
||||
:marked
|
||||
|
@ -82,7 +82,7 @@ code-example(format="." language="bash").
|
|||
|
||||
在`app`目录下添加一个名叫`hero-detail.component.ts`的文件,并且创建`HeroDetailComponent`。代码如下:
|
||||
|
||||
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'v1', 'hero-detail.component.ts (初始版本)')(format=".")
|
||||
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'v1', 'app/hero-detail.component.ts (initial version)')(format=".")
|
||||
.l-sub-section
|
||||
:marked
|
||||
### Naming conventions
|
||||
|
@ -100,10 +100,11 @@ code-example(format="." language="bash").
|
|||
|
||||
我们的所有组件名都以`Component`结尾。所有组件的文件名都以`.component`结尾。
|
||||
|
||||
We spell our file names in lower dash case (AKA "kebab-case") so we don't worry about
|
||||
We spell our file names in lower **[dash case](../guide/glossary.html#!#dash-case)**
|
||||
(AKA **[kebab-case](../guide/glossary.html#!#kebab-case)**) so we don't worry about
|
||||
case sensitivity on the server or in source control.
|
||||
|
||||
这里我们使用小写中线命名法(也叫烤串命名法)拼写文件名,所以不用担心它在服务器或者版本控制系统中出现大小写问题。
|
||||
这里我们使用小写**[中线命名法](../guide/glossary.html#!#dash-case)**(也叫**[烤串命名法](../guide/glossary.html#!#kebab-case)**)拼写文件名,所以不用担心它在服务器或者版本控制系统中出现大小写问题。
|
||||
<!-- TODO
|
||||
.l-sub-section
|
||||
:marked
|
||||
|
@ -145,7 +146,8 @@ code-example(format="." language="bash").
|
|||
`HeroDetailComponent`组件将会有一个`hero`属性,而不是`selectedHero`属性。
|
||||
所以,我们要把模板中的所有`selectedHero`替换为`hero`。只改这些就够了。
|
||||
最终结果如下所示:
|
||||
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'template', 'hero-detail.component.ts (模板)')(format=".")
|
||||
|
||||
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'template', 'app/hero-detail.component.ts (template)')(format=".")
|
||||
|
||||
:marked
|
||||
Now our hero detail layout exists only in the `HeroDetailComponent`.
|
||||
|
@ -169,16 +171,16 @@ code-example(format="." language="bash").
|
|||
|
||||
要解决这个问题,我们也得从`app.component.ts`文件中把`Hero`类移到属于它自己的`hero.ts`文件中。
|
||||
|
||||
+makeExample('toh-3/ts/app/hero.ts', null, 'hero.ts (导出Hero类)')(format=".")
|
||||
+makeExample('toh-3/ts/app/hero.ts', '', 'app/hero.ts')(format=".")
|
||||
|
||||
:marked
|
||||
We export the `Hero` class from `hero.ts` because we'll need to reference it in both component files.
|
||||
Add the following import statement near the top of both `app.component.ts` and `hero-detail.component.ts`.
|
||||
Add the following import statement near the top of **both `app.component.ts` and `hero-detail.component.ts`**.
|
||||
|
||||
我们得从`hero.ts`中导出`Hero`类,因为我们要从那些组件文件中引用它。
|
||||
在`app.component.ts`和`hero-detail.component.ts`的顶部添加下列import语句:
|
||||
在**`app.component.ts`和`hero-detail.component.ts`**的顶部添加下列import语句:
|
||||
|
||||
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'hero-import', 'hero-detail.component.ts与app.component.ts(导入Hero类)')
|
||||
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'hero-import')
|
||||
|
||||
:marked
|
||||
#### The *hero* property is an ***input***
|
||||
|
@ -268,7 +270,7 @@ code-example(format=".").
|
|||
|
||||
`AppComponent`的模板是这样的:
|
||||
|
||||
+makeExample('toh-3/ts/app/app.component.ts', 'hero-detail-template', 'app.component.ts (Template)')(format='.')
|
||||
+makeExample('toh-3/ts/app/app.component.ts', 'hero-detail-template', 'app.component.ts (template)')(format='.')
|
||||
:marked
|
||||
Thanks to the binding, the `HeroDetailComponent` should receive the hero from the `AppComponent` and display that hero's detail beneath the list.
|
||||
The detail should update every time the user picks a new hero.
|
||||
|
|
|
@ -22,7 +22,7 @@ include ../_util-fns
|
|||
在这种方式下,借助mock服务来对组件进行单元测试也会更容易。
|
||||
|
||||
Because data services are invariably asynchronous,
|
||||
we'll finish the chapter with a promise-based version of the data service.
|
||||
we'll finish the chapter with a **!{_Promise}**-based version of the data service.
|
||||
|
||||
因为数据服务通常都是异步的,所以在本章的最后,我们会把它重构为基于承诺(Promise,一种异步编程模式)的版本。
|
||||
|
||||
|
@ -95,7 +95,7 @@ code-example(language="bash").
|
|||
目前,`AppComponent`显示的是我们自定义的一个mock英雄数据。
|
||||
我们可改进的地方至少有两个:首先,定义英雄的数据不该是该组件的任务。其次,想把这份英雄列表的数据共享给其它组件和视图可不那么容易。
|
||||
|
||||
We can refactor this hero data acquisition business to a single service that provides heroes and
|
||||
We can refactor this hero data acquisition business to a single service that provides heroes, and
|
||||
share that service with all components that need heroes.
|
||||
|
||||
我们可以把提供英雄数据的任务重构为一个单独的服务,它将提供英雄数据,并且把这个服务在所有需要英雄数据的组件之间共享。
|
||||
|
@ -108,7 +108,7 @@ code-example(language="bash").
|
|||
.l-sub-section
|
||||
:marked
|
||||
We've adopted a convention in which we spell the name of a service in lowercase followed by `.service`.
|
||||
If the service name were multi-word, we'd spell the base filename with lower dash case (AKA "kebab-case").
|
||||
If the service name were multi-word, we'd spell the base filename in lower [dash-case](../guide/glossary.html#!#dash-case).
|
||||
The `SpecialSuperHeroService` would be defined in the `special-super-hero.service.ts` file.
|
||||
|
||||
我们遵循的文件命名约定是:服务名称的小写形式(基本名),加上`.service`后缀。
|
||||
|
@ -119,7 +119,7 @@ code-example(language="bash").
|
|||
|
||||
我们把这个类命名为`HeroService`,并且导出它,以供别人使用。
|
||||
|
||||
+makeExample('toh-4/ts/app/hero.service.1.ts', 'empty-class', 'hero.service.ts (导出类)')(format=".")
|
||||
+makeExample('toh-4/ts/app/hero.service.1.ts', 'empty-class', 'app/hero.service.ts (starting point)')(format=".")
|
||||
|
||||
:marked
|
||||
### Injectable Services
|
||||
|
@ -150,7 +150,8 @@ code-example(language="bash").
|
|||
Add a `getHeroes` method stub.
|
||||
|
||||
添加一个名叫`getHeros`的桩方法。
|
||||
+makeExample('toh-4/ts/app/hero.service.1.ts', 'getHeroes-stub', 'hero.service.ts (getHeroes桩方法)')(format=".")
|
||||
|
||||
+makeExample('toh-4/ts/app/hero.service.1.ts', 'getHeroes-stub', 'app/hero.service.ts (getHeroes stub)')(format=".")
|
||||
:marked
|
||||
We're holding back on the implementation for a moment to make an important point.
|
||||
|
||||
|
@ -184,7 +185,8 @@ code-example(language="bash").
|
|||
|
||||
从`app.component.ts`文件中剪切`HEROS`数组,并把它粘贴到`app`目录下一个名叫`mock-heroes.ts`的文件中。
|
||||
我们还要把`import {Hero}...`语句拷贝过来,因为我们的英雄数组用到了`Hero`类。
|
||||
+makeExample('toh-4/ts/app/mock-heroes.ts', null, 'mock-heroes.ts (英雄数组)')
|
||||
|
||||
+makeExample('toh-4/ts/app/mock-heroes.ts', null, 'app/mock-heroes.ts')
|
||||
:marked
|
||||
We export the `HEROES` constant so we can import it elsewhere — such as our `HeroService`.
|
||||
|
||||
|
@ -194,7 +196,8 @@ code-example(language="bash").
|
|||
we leave behind an uninitialized `heroes` property:
|
||||
|
||||
同时,回到刚剪切出`HEROES`数组的`app.component.ts`文件,我们留下了一个尚未初始化的`heroes`属性:
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'heroes-prop', 'app.component.ts (heroes属性)')(format=".")
|
||||
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'heroes-prop', 'app/app.component.ts (heroes property)')(format=".")
|
||||
:marked
|
||||
### Return Mocked Heroes
|
||||
### 返回模拟的英雄数据
|
||||
|
@ -203,7 +206,8 @@ code-example(language="bash").
|
|||
|
||||
回到`HeroService`,我们导入`HEROES`常量,并在`getHeroes`方法中返回它。
|
||||
我们的`HeroService`服务现在看起来是这样:
|
||||
+makeExample('toh-4/ts/app/hero.service.1.ts', null, 'hero.service.ts')(format=".")
|
||||
|
||||
+makeExample('toh-4/ts/app/hero.service.1.ts', null, 'app/hero.service.ts')(format=".")
|
||||
:marked
|
||||
### Use the Hero Service
|
||||
### 使用HeroService服务
|
||||
|
@ -214,7 +218,8 @@ code-example(language="bash").
|
|||
We begin, as usual, by importing the thing we want to use, the `HeroService`.
|
||||
|
||||
通常,我们会从导入要用的东西开始,比如`HeroService`。
|
||||
+makeExample('toh-4/ts/app/app.component.ts', 'hero-service-import', 'app.component.ts (导入HeroService)')
|
||||
|
||||
+makeExcerpt('toh-4/ts/app/app.component.ts', 'hero-service-import')
|
||||
:marked
|
||||
Importing the service allows us to *reference* it in our code.
|
||||
How should the `AppComponent` acquire a runtime concrete `HeroService` instance?
|
||||
|
@ -223,10 +228,13 @@ code-example(language="bash").
|
|||
`AppComponent`该如何在运行中获得一个具体的`HeroService`实例呢?
|
||||
|
||||
### Do we *new* the *HeroService*? No way!
|
||||
|
||||
### 我们要自己 *new* 出这个 *HeroService* 吗?不!
|
||||
We could create a new instance of the `HeroService` with "new" like this:
|
||||
|
||||
We could create a new instance of the `HeroService` with `new` like this:
|
||||
|
||||
固然,我们可以使用`new`关键字来创建`HeroService`的实例,就像这样:
|
||||
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'new-service')(format=".")
|
||||
:marked
|
||||
That's a bad idea for several reasons including
|
||||
|
@ -242,7 +250,7 @@ code-example(language="bash").
|
|||
如果有一天我们修改了`HeroService`的构造函数,我们不得不找出创建过此服务的每一处代码,并修改它。
|
||||
而给代码打补丁的行为容易导致错误,并增加了测试的负担。
|
||||
|
||||
* We create a new service each time we use "new".
|
||||
* We create a new service each time we use `new`.
|
||||
What if the service should cache heroes and share that cache with others?
|
||||
We couldn't do that.
|
||||
|
||||
|
@ -274,15 +282,20 @@ code-example(language="bash").
|
|||
Two lines replace the one line that created with *new*:
|
||||
|
||||
用这两行代码代替用`new`时的一行:
|
||||
1. we add a constructor.
|
||||
1. 添加一个构造函数
|
||||
1. we add to the component's `providers` metadata
|
||||
1. 添加组件的`providers`元数据
|
||||
|
||||
1. We add a constructor that also defines a private property.
|
||||
|
||||
1. 我们添加了一个构造函数,同时还定义了一个私有属性。
|
||||
|
||||
1. We add to the component's `providers` metadata.
|
||||
|
||||
1. 我们添加了组件的`providers`元数据
|
||||
|
||||
Here's the constructor:
|
||||
|
||||
下面就是这个构造函数:
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'ctor', 'app.component.ts (构造函数)')
|
||||
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'ctor', 'app/app.component.ts (constructor)')
|
||||
:marked
|
||||
The constructor itself does nothing. The parameter simultaneously
|
||||
defines a private `heroService` property and identifies it as a `HeroService` injection site.
|
||||
|
@ -305,7 +318,8 @@ code-example(language="bash").
|
|||
|
||||
*注入器*还不知道该如何创建`HeroService`。
|
||||
如果现在运行我们的代码,Angular就会失败,并报错:
|
||||
code-example(format="." language="html").
|
||||
|
||||
code-example(format="nocode").
|
||||
EXCEPTION: No provider for HeroService! (AppComponent -> HeroService)
|
||||
(异常:没有HeroService的供应商!(AppComponent -> HeroService))
|
||||
:marked
|
||||
|
@ -315,7 +329,8 @@ code-example(format="." language="html").
|
|||
|
||||
我们还得注册一个`HeroService`**供应商**,来告诉*注入器*如何创建`HeroService`。
|
||||
要做到这一点,我们应该在`@Component`组件的元数据底部添加`providers`数组属性如下:
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'providers', 'app.component.ts (提供HeroService)')
|
||||
|
||||
+makeExcerpt('toh-4/ts/app/app.component.1.ts', 'providers')
|
||||
:marked
|
||||
The `providers` array tells Angular to create a fresh instance of the `HeroService` when it creates a new `AppComponent`.
|
||||
The `AppComponent` can use that service to get heroes and so can every child component of its component tree.
|
||||
|
@ -338,7 +353,8 @@ a#child-component
|
|||
We don't really need a dedicated method to wrap one line. We write it anyway:
|
||||
|
||||
在真实的世界中,我们并不需要把一行代码包装成一个专门的方法,但无论如何,我们在演示代码中先这么写:
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'getHeroes', 'app.component.ts (getHeroes)')(format=".")
|
||||
|
||||
+makeExcerpt('toh-4/ts/app/app.component.1.ts', 'getHeroes')
|
||||
|
||||
<a id="oninit"></a>
|
||||
:marked
|
||||
|
@ -385,13 +401,15 @@ a#child-component
|
|||
Here's the essential outline for the `OnInit` interface:
|
||||
|
||||
这是`OnInit`接口的基本轮廓:
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'on-init', 'app.component.ts (OnInit协议)')(format=".")
|
||||
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'on-init', 'app/app.component.ts (ngOnInit stub)')(format=".")
|
||||
:marked
|
||||
We write an `ngOnInit` method with our initialization logic inside and leave it to Angular to call it
|
||||
at the right time. In our case, we initialize by calling `getHeroes`.
|
||||
|
||||
我们写下带有初始化逻辑的`ngOnInit`方法,然后留给Angular,供其在正确的时机调用。在这个例子中,我们通过调用`getHeroes`来完成初始化。
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'ng-on-init', 'app.component.ts (OnInit协议)')(format=".")
|
||||
|
||||
+makeExcerpt('toh-4/ts/app/app.component.1.ts', 'ng-on-init')
|
||||
:marked
|
||||
Our application should be running as expected, showing a list of heroes and a hero detail view
|
||||
when we click on a hero name.
|
||||
|
@ -402,12 +420,17 @@ a#child-component
|
|||
|
||||
我们就快完成了,但还有点事情不太对劲儿。
|
||||
|
||||
## Async Services and Promises
|
||||
<a id="async"></a>
|
||||
|
||||
## Async Services and !{_Promise}s
|
||||
|
||||
## 异步服务与承诺(Promise)
|
||||
|
||||
Our `HeroService` returns a list of mock heroes immediately.
|
||||
Its `getHeroes` signature is synchronous
|
||||
|
||||
我们的`HeroService`立即返回一个模拟的英雄列表,它的`getHeroes`函数签名是同步的。
|
||||
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'get-heroes')(format=".")
|
||||
:marked
|
||||
Ask for heroes and they are there in the returned result.
|
||||
|
@ -427,14 +450,15 @@ a#child-component
|
|||
|
||||
我们不得不使用一些异步技术,而这将改变`getHeroes`方法的签名。
|
||||
|
||||
We'll use *promises*.
|
||||
We'll use *!{_Promise}s*.
|
||||
|
||||
我们将使用 *承诺(Promise)* 。
|
||||
|
||||
### The Hero Service makes a promise
|
||||
### The Hero Service makes a !{_Promise}
|
||||
|
||||
### `HeroService`会生成一个承诺
|
||||
|
||||
A **promise** is ... well it's a promise to call us back later when the results are ready.
|
||||
A **!{_Promise}** is ... well it's a promise to call us back later when the results are ready.
|
||||
We ask an asynchronous service to do some work and give it a callback function.
|
||||
It does that work (somewhere) and eventually it calls our function with the results of the work or an error.
|
||||
|
||||
|
@ -447,36 +471,42 @@ a#child-component
|
|||
|
||||
这里只是粗浅的说说,要了解更多,请参见[这里](http://exploringjs.com/es6/ch_promises.html)或在Web上搜索其它学习资源。
|
||||
:marked
|
||||
Update the `HeroService` with this promise-returning `getHeroes` method:
|
||||
Update the `HeroService` with this !{_Promise}-returning `getHeroes` method:
|
||||
|
||||
把`HeroService`的`getHeroes`方法改写为返回承诺的形式:
|
||||
+makeExample('toh-4/ts/app/hero.service.ts', 'get-heroes', 'hero.service.ts (getHeroes)')(format=".")
|
||||
|
||||
+makeExample('toh-4/ts/app/hero.service.ts', 'get-heroes', 'app/hero.service.ts (excerpt)')(format=".")
|
||||
:marked
|
||||
We're still mocking the data. We're simulating the behavior of an ultra-fast, zero-latency server,
|
||||
by returning an **immediately resolved promise** with our mock heroes as the result.
|
||||
by returning an **immediately resolved !{_Promise}** with our mock heroes as the result.
|
||||
|
||||
我们继续使用模拟数据。我们通过返回一个 *立即解决的承诺* 的方式,模拟了一个超快、零延迟的超级服务器。
|
||||
### Act on the Promise
|
||||
|
||||
### Act on the !{_Promise}
|
||||
|
||||
### 基于承诺的行动
|
||||
|
||||
Returning to the `AppComponent` and its `getHeroes` method, we see that it still looks like this:
|
||||
|
||||
回到`AppComponent`和它的`getHeroes`方法,我们看到它看起来还是这样的:
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'getHeroes', 'app.component.ts (getHeroes - 老的)')(format=".")
|
||||
|
||||
+makeExample('toh-4/ts/app/app.component.1.ts', 'getHeroes', 'app/app.component.ts (getHeroes - old)')(format=".")
|
||||
:marked
|
||||
As a result of our change to `HeroService`, we're now setting `this.heroes` to a promise rather than an array of heroes.
|
||||
As a result of our change to `HeroService`, we're now setting `this.heroes` to a !{_Promise} rather than an array of heroes.
|
||||
|
||||
在修改了`HeroService`之后,我们还要把`this.heroes`替换为一个承诺,而不再是一个英雄数组。
|
||||
|
||||
We have to change our implementation to *act on the promise when it resolves*.
|
||||
When the promise resolves successfully, *then* we will have heroes to display.
|
||||
We have to change our implementation to *act on the !{_Promise} when it resolves*.
|
||||
When the !{_Promise} resolves successfully, *then* we will have heroes to display.
|
||||
|
||||
我们得修改这个实现,把它变成*基于承诺*的,并在承诺的事情被解决时再行动。
|
||||
一旦承诺的事情被成功解决,我们就会显示英雄数据。
|
||||
|
||||
We pass our callback function as an argument to the promise's **then** method:
|
||||
We pass our callback function as an argument to the !{_Promise}'s **then** method:
|
||||
|
||||
我们把回调函数作为参数传给承诺对象的**then**函数:
|
||||
+makeExample('toh-4/ts/app/app.component.ts', 'get-heroes', 'app.component.ts (getHeroes - 修改版)')(format=".")
|
||||
|
||||
+makeExample('toh-4/ts/app/app.component.ts', 'get-heroes', 'app/app.component.ts (getHeroes - revised)')(format=".")
|
||||
.l-sub-section
|
||||
:marked
|
||||
The [ES2015 arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
|
||||
|
@ -520,6 +550,8 @@ a#child-component
|
|||
.file typings ...
|
||||
.file index.html
|
||||
.file package.json
|
||||
.file styles.css
|
||||
.file systemjs.config.js
|
||||
.file tsconfig.json
|
||||
.file typings.json
|
||||
:marked
|
||||
|
@ -543,16 +575,25 @@ a#child-component
|
|||
|
||||
来盘点一下我们已经构建完的部分。
|
||||
|
||||
* We created a service class that can be shared by many components
|
||||
* 我们创建了一个能被多个组件共享的服务类
|
||||
* We used the `ngOnInit` Lifecycle Hook to get our heroes when our `AppComponent` activates
|
||||
* We created a service class that can be shared by many components.
|
||||
|
||||
* 我们创建了一个能被多个组件共享的服务类。
|
||||
|
||||
* We used the `ngOnInit` Lifecycle Hook to get our heroes when our `AppComponent` activates.
|
||||
|
||||
* 我们使用`ngOnInit`生命周期钩子,以便在`AppComponent`激活时获取英雄数据。
|
||||
* We defined our `HeroService` as a provider for our `AppComponent`
|
||||
* 我们把`HeroService`定义为`AppComponent`的一个供应商
|
||||
* We created mock hero data and imported them into our service
|
||||
* 我们创建了一个模拟的英雄数据,并把它导入我们的服务中
|
||||
* We designed our service to return a promise and our component to get our data from the promise
|
||||
* 我们把服务改造为返回承诺的,并让组件从承诺获取数据
|
||||
|
||||
* We defined our `HeroService` as a provider for our `AppComponent`.
|
||||
|
||||
* 我们把`HeroService`定义为`AppComponent`的一个供应商。
|
||||
|
||||
* We created mock hero data and imported them into our service.
|
||||
|
||||
* 我们创建了一个模拟的英雄数据,并把它导入我们的服务中。
|
||||
|
||||
* We designed our service to return a !{_Promise} and our component to get our data from the !{_Promise}.
|
||||
|
||||
* 我们把服务改造为返回承诺的,并让组件从承诺获取数据。
|
||||
|
||||
p Run the #[+liveExampleLink2('', 'toh-4')] for this part.
|
||||
|
||||
|
@ -586,10 +627,11 @@ p 运行这部分的#[+liveExampleLink2('在线例子', 'toh-4')]。
|
|||
Import the `Hero` symbol and add the following `getHeroesSlowly` method to the `HeroService`
|
||||
|
||||
导入`Hero`类,并且在`HeroService`中添加如下的`getHeroesSlowly`方法:
|
||||
+makeExample('toh-4/ts/app/hero.service.ts', 'get-heroes-slowly', 'hero.service.ts (getHeroesSlowly)')(format=".")
|
||||
|
||||
+makeExample('toh-4/ts/app/hero.service.ts', 'get-heroes-slowly', 'app/hero.service.ts (getHeroesSlowly)')(format=".")
|
||||
:marked
|
||||
Like `getHeroes`, it also returns a promise.
|
||||
But this promise waits 2 seconds before resolving the promise with mock heroes.
|
||||
Like `getHeroes`, it also returns a !{_Promise}.
|
||||
But this !{_Promise} waits 2 seconds before resolving the !{_Promise} with mock heroes.
|
||||
|
||||
像`getHeroes`一样,它也返回一个承诺。
|
||||
但是,这个承诺会在使用模拟数据完成任务之前等待两秒钟。
|
||||
|
|
|
@ -6,13 +6,13 @@ include ../_util-fns
|
|||
We received new requirements for our Tour of Heroes application:
|
||||
|
||||
我们收到了一份《英雄指南》的新需求:
|
||||
* add a *Dashboard* view.
|
||||
* Add a *Dashboard* view.
|
||||
* 添加一个*仪表盘*视图。
|
||||
* navigate between the *Heroes* and *Dashboard* views.
|
||||
* Navigate between the *Heroes* and *Dashboard* views.
|
||||
* 在*英雄列表*和*仪表盘*视图之间导航。
|
||||
* clicking on a hero in either view navigates to a detail view of the selected hero.
|
||||
* Clicking on a hero in either view navigates to a detail view of the selected hero.
|
||||
* 无论在哪个视图中点击一个英雄,都会导航到该英雄的详情页。
|
||||
* clicking a *deep link* in an email opens the detail view for a particular hero;
|
||||
* Clicking a *deep link* in an email opens the detail view for a particular hero;
|
||||
* 在邮件中点击一个*深链接*,会直接打开一个特定英雄的详情视图。
|
||||
|
||||
When we’re done, users will be able to navigate the app like this:
|
||||
|
@ -92,14 +92,14 @@ code-example(language="bash").
|
|||
|
||||
下面是我们的计划
|
||||
|
||||
* turn `AppComponent` into an application shell that only handles navigation.
|
||||
* 把`AppComponent`变成应用程序的“壳”,它只处理导航。
|
||||
* relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`
|
||||
* 把现在由`AppComponent`关注的*英雄们*移到一个独立的`HeroesComponent`中
|
||||
* add routing
|
||||
* 添加路由
|
||||
* create a new `DashboardComponent`
|
||||
* 添加一个新的`DashboardComponent`组件
|
||||
* turn `AppComponent` into an application shell that only handles navigation,
|
||||
* 把`AppComponent`变成应用程序的“壳”,它只处理导航,
|
||||
* relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`,
|
||||
* 把现在由`AppComponent`关注的*英雄们*移到一个独立的`HeroesComponent`中,
|
||||
* add routing,
|
||||
* 添加路由,
|
||||
* create a new `DashboardComponent`,
|
||||
* 添加一个新的`DashboardComponent`组件,
|
||||
* tie the *Dashboard* into the navigation structure.
|
||||
* 把*仪表盘*加入导航结构中。
|
||||
|
||||
|
@ -148,7 +148,7 @@ code-example(language="bash").
|
|||
* 把`my-app`选择器改名为`my-heroes`。
|
||||
|
||||
:marked
|
||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'heroes-component-renaming', 'app/heroes.component.ts (改名)')(format=".")
|
||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'heroes-component-renaming', 'app/heroes.component.ts (showing renamings only)')(format=".")
|
||||
|
||||
:marked
|
||||
## Create *AppComponent*
|
||||
|
@ -249,12 +249,14 @@ code-example(language="bash").
|
|||
and a configuration decorator (`RouteConfig`). We'll import them all together:
|
||||
|
||||
Angular路由器是由多个服务(`ROUTER_PROVIDERS`)和多个指令(`ROUTER_DIRECTIVES`)以及一个配置装饰器(`RouteConfig`)组成的。我们一次性导入它们。
|
||||
+makeExample('toh-5/ts/app/app.component.2.ts', 'import-router', 'app.component.ts (导入router)')(format=".")
|
||||
|
||||
+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.
|
||||
|
||||
接下来,我们要更新`directives`和`providers`元数据数组,来包含这些路由器部件。
|
||||
+makeExample('toh-5/ts/app/app.component.2.ts', 'directives-and-providers', 'app.component.ts (directives和providers)')(format=".")
|
||||
|
||||
+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.
|
||||
|
@ -279,7 +281,8 @@ code-example(language="bash").
|
|||
Let's define our first route, a route to the `HeroesComponent`.
|
||||
|
||||
我们来定义第一个路由 —— 到`HeroesComponent`的路由。
|
||||
+makeExample('toh-5/ts/app/app.component.2.ts', 'route-config', 'app.component.ts (英雄列表的RouteConfig)')(format=".")
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.2.ts', 'route-config', 'app/app.component.ts (RouteConfig for heroes)')(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.
|
||||
|
@ -337,7 +340,8 @@ code-example(language="bash").
|
|||
The revised template looks like this:
|
||||
|
||||
修改过的模板是这样的:
|
||||
+makeExample('toh-5/ts/app/app.component.2.ts', 'template', 'app.component.ts (英雄列表模板)')(format=".")
|
||||
|
||||
+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.
|
||||
We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to an array
|
||||
|
@ -418,7 +422,8 @@ code-example(language="bash").
|
|||
Add the following `'Dashboard'` route definition to the `@RouteConfig` array of definitions.
|
||||
|
||||
然后把下列`'Dashboard'`路由的定义添加到`@RouteConfig`数组中。
|
||||
+makeExample('toh-5/ts/app/app.component.ts','dashboard-route', 'app.component.ts (仪表盘路由)')(format=".")
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.ts','dashboard-route', 'app/app.component.ts (Dashboard route)')(format=".")
|
||||
.l-sub-section
|
||||
:marked
|
||||
**useAsDefault**
|
||||
|
@ -440,7 +445,7 @@ code-example(language="bash").
|
|||
|
||||
最后,在模板上添加一个到仪表盘的导航链接,就放在*英雄(Heroes)*链接的上方。
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.ts','template', 'app.component.ts (模板)')(format=".")
|
||||
+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 `<nav>` tags.
|
||||
|
@ -478,7 +483,8 @@ code-example(language="bash").
|
|||
Create that file with these contents:
|
||||
|
||||
使用下列内容创建文件:
|
||||
+makeExample('toh-5/ts/app/dashboard.component.html', null, 'dashboard.component.html')(format=".")
|
||||
|
||||
+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 added extra `<div>` elements to help with styling later in this chapter.
|
||||
|
@ -506,10 +512,10 @@ code-example(language="bash").
|
|||
回忆一下,在前面的章节中,我们从`HeroesComponent`的`providers`数组中移除了`HeroService`服务,并把它添加到顶级组件`AppComponent`的`providers`数组中。
|
||||
|
||||
That move created a singleton `HeroService` instance, available to *all* components of the application.
|
||||
We'll inject and use it here in the `DashboardComponent` .
|
||||
Angular will inject `HeroService` and we'll use it here in the `DashboardComponent`.
|
||||
|
||||
这个改动创建了一个`HeroService`的单例对象,它对应用中的*所有*组件都有效。
|
||||
在`DashboardComponent`组件中,我们要把它注入进来,并使用它。
|
||||
在`DashboardComponent`组件中,Angular会把`HeroService`注入进来,我们就能在`DashboardComponent`中使用它了。
|
||||
|
||||
### Get heroes
|
||||
### 获取英雄数组
|
||||
|
@ -614,7 +620,8 @@ code-example(format='').
|
|||
Here's the *route definition* we'll use.
|
||||
|
||||
下面是我们将使用的*路由定义*。
|
||||
+makeExample('toh-5/ts/app/app.component.ts','hero-detail-route', 'app/app.component.ts (到HeroDetailComponent的路由)')(format=".")
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.ts','hero-detail-route', 'app/app.component.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`
|
||||
when navigating to the `HeroDetailComponent`.
|
||||
|
@ -654,10 +661,11 @@ code-example(format='').
|
|||
## Revise the *HeroDetailComponent*
|
||||
## 修改*HeroDetailComponent*
|
||||
|
||||
Before we rewrite the `HeroDetailComponent`, let's remember what it looks like now:
|
||||
Before we rewrite the `HeroDetailComponent`, let's review what it looks like now:
|
||||
|
||||
在重写`HeroDetailComponent`之前,我们先记住它现在的样子:
|
||||
+makeExample('toh-4/ts/app/hero-detail.component.ts', null, 'app/hero-detail.component.ts (当前)')
|
||||
在重写`HeroDetailComponent`之前,我们先看看它现在的样子:
|
||||
|
||||
+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.
|
||||
|
||||
|
@ -665,7 +673,7 @@ code-example(format='').
|
|||
|
||||
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` from storage.
|
||||
and use the `HeroService` to fetch the hero with that `id`.
|
||||
|
||||
我们不会再从父组件的属性绑定中取得英雄数据。
|
||||
新的`HeroDetailComponent`应该从路由器的`RouteParams`服务中取得`id`参数,并通过`HeroService`服务获取具有这个指定`id`的英雄数据。
|
||||
|
@ -675,7 +683,7 @@ code-example(format='').
|
|||
我们需要一个import语句,来引用`RouteParams`。
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-route-params')(format=".")
|
||||
:marked
|
||||
We import the `HeroService`so we can fetch a hero`.
|
||||
We import the `HeroService`so we can fetch a hero.
|
||||
|
||||
我们导入了`HeroService`,现在就能获取一个英雄了。
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-hero-service')(format=".")
|
||||
|
@ -775,15 +783,18 @@ code-example(format='').
|
|||
Here's the (nearly) finished `HeroDetailComponent`:
|
||||
|
||||
下面是(几乎)完成的`HeroDetailComponent`:
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'v2', 'app/hero-detail.component.ts (最新版)')(format=".")
|
||||
|
||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'v2', 'app/hero-detail.component.ts (latest)')(format=".")
|
||||
:marked
|
||||
|
||||
|
||||
.l-main-section
|
||||
: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..
|
||||
|
||||
When a user selects a hero in the dashboard, the app should navigate to the `HeroDetailComponent` to view and edit the selected hero.
|
||||
|
||||
当用户从仪表盘中选择了一位英雄时,本应用要导航到`HeroDetailComponent`以查看和编辑所选的英雄。
|
||||
|
||||
|
@ -823,7 +834,7 @@ code-example(format='').
|
|||
+makeExample('toh-5/ts/app/app.component.ts','hero-detail-route', 'app/app.component.ts (英雄详情路由)')(format=".")
|
||||
:marked
|
||||
The `DashboardComponent` doesn't have the router yet. We obtain it in the usual way:
|
||||
`import` the `router` reference and inject it in the constructor (along with the `HeroService`):
|
||||
import the `router` reference and inject it in the constructor (along with the `HeroService`):
|
||||
|
||||
`DashboardComponent`还没有路由器。我们使用常规的方式为它加上路由:
|
||||
`import` `router`对象的引用,并且把它注入到构造函数中(就像`HeroService`那样):
|
||||
|
@ -884,7 +895,7 @@ figure.image-display
|
|||
### 使用*UpperCasePipe*格式化
|
||||
|
||||
Notice that the hero's name is displayed in CAPITAL LETTERS. That's the effect of the `UpperCasePipe`
|
||||
that we slipped into the interpolation binding. Look for it right after the pipe operator, ( | ).
|
||||
that we slipped into the interpolation binding. Look for it right after the pipe operator ( | ).
|
||||
|
||||
注意,英雄的名字全被显示成大写字母。那是 `UpperCasePipe`的效果,借助它,我们能插手“插值表达式绑定”的过程。去管道操作符 ( | ) 后面找它。
|
||||
+makeExample('toh-5/ts/app/heroes.component.html','pipe')(format=".")
|
||||
|
@ -931,9 +942,10 @@ figure.image-display
|
|||
所以我们可以从元数据的`directives`数组中移除它。`directives`数组现在没东西了,因此我们也把它删掉。
|
||||
我们也同样可以删掉`import` `HeroDetailComponent`的语句。
|
||||
|
||||
The revised component metadata looks like this:
|
||||
The revised `@Component` looks like this:
|
||||
|
||||
修改过的`@Component`是这样的:
|
||||
|
||||
修改过的组件数据是这样的:
|
||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'metadata', 'app/heroes.component.ts (revised metadata)')(format=".")
|
||||
:marked
|
||||
Now we can see what's going on as we update the component class along the same lines as the dashboard:
|
||||
|
@ -944,7 +956,7 @@ figure.image-display
|
|||
1. Inject the `router` in the constructor (along with the `HeroService`)
|
||||
1. 把`router`注入到构造函数中(就像`HeroService`那样)
|
||||
1. Implement the `gotoDetail` method by calling the `router.navigate` method
|
||||
with a two-part 'HeroDetail' *link parameters array*.
|
||||
with a two-part `HeroDetail` *link parameters array*.
|
||||
1. 实现`gotoDetail`方法:以`HeroDetail`和*链接参数数组*为参数调用`router.navigate`方法。
|
||||
|
||||
Here's the revised component class:
|
||||
|
@ -1038,7 +1050,8 @@ figure.image-display
|
|||
Add a `app.component.css` file to the `app` folder with the following content.
|
||||
|
||||
在`app`目录下添加一个`app.component.css`文件,内容如下:
|
||||
+makeExample('toh-5/ts/app/app.component.css', 'css', 'app/app.component.css (导航样式)')
|
||||
|
||||
+makeExample('toh-5/ts/app/app.component.css', '', 'app/app.component.css (navigation styles)')
|
||||
.l-sub-section
|
||||
:marked
|
||||
**The *router-link-active* class**
|
||||
|
@ -1069,17 +1082,32 @@ figure.image-display
|
|||
|
||||
我们也可以在所有组件之外创建*应用级*样式。
|
||||
|
||||
Our designers provided some basic styles to apply to elements across the entire app.
|
||||
Add the following to a new file named `styles.css` in the root folder.
|
||||
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
|
||||
[QuickStart, "Add some style"](../quickstart.html#!#add-some-style)).
|
||||
Here is an excerpt.
|
||||
|
||||
我们的设计师提供了一组基础样式,这些样式应用到的元素横跨整个应用。
|
||||
把下面这个名叫`styles.css`的新文件添加到根目录中:
|
||||
+makeExample('toh-5/ts/styles.1.css', '', 'styles.css (应用级样式)')(format=".")
|
||||
这些和我们前面引入的主样式全集是一样的(参见
|
||||
[快速起步, "添加一些样式"](../quickstart.html#!#add-some-style))。
|
||||
下面是摘录:
|
||||
|
||||
+makeExample('toh-5/ts/styles.1.css', 'toh-excerpt', 'styles.css (app styles excerpt)')(format=".")
|
||||
|
||||
- var styles_css = 'https://raw.githubusercontent.com/angular/angular.io/master/public/docs/_examples/styles.css'
|
||||
|
||||
:marked
|
||||
Reference this stylesheet within the `index.html` in the traditional manner.
|
||||
Add a new file named `styles.css` in the root folder, if there isn't one already.
|
||||
Ensure that it contains the [master styles given here](!{styles_css}).
|
||||
|
||||
如果在根目录下没有一个名叫`styles.css`的文件,就添加它。
|
||||
确保它包含[这里给出的主样式](!{styles_css})。
|
||||
|
||||
Also ensure this stylesheet is referenced in the traditional manner within `index.html`.
|
||||
|
||||
同时确保这个样式表在`index.html`中被使用传统方式引用了。
|
||||
|
||||
用传统的方式,在`index.html`中引用这个样式表。
|
||||
+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!
|
||||
|
@ -1132,7 +1160,6 @@ p.
|
|||
.file systemjs.config.json
|
||||
.file tsconfig.json
|
||||
.file typings.json
|
||||
:marked
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
|
@ -1144,17 +1171,29 @@ p.
|
|||
We travelled a great distance in this chapter.
|
||||
|
||||
在本章中,我们往前走了很远:
|
||||
|
||||
- We added the Angular *Component Router* to navigate among different components.
|
||||
|
||||
- 我们添加了Angular*组件路由器*在各个不同组件之间导航。
|
||||
- We learned how to create router links to represent navigation menu items
|
||||
|
||||
- We learned how to create router links to represent navigation menu items.
|
||||
|
||||
- 我们学会了如何创建路由链接来表示导航栏的菜单项。
|
||||
- We used router parameters to navigate to the details of user selected hero
|
||||
|
||||
- We used router parameters to navigate to the details of user selected hero.
|
||||
|
||||
- 我们使用路由参数来导航到用户所选的英雄详情。
|
||||
- We shared the `HeroService` among multiple components
|
||||
|
||||
- We shared the `HeroService` among multiple components.
|
||||
|
||||
- 我们在多个组件之间共享了`HeroService`服务。
|
||||
|
||||
- We moved HTML and CSS out of the component file and into their own files.
|
||||
|
||||
- 我们把HTML和CSS从组件中移出来,放到了它们自己的文件中。
|
||||
- We added the `uppercase` pipe to format data
|
||||
|
||||
- We added the `uppercase` pipe to format data.
|
||||
|
||||
- 我们添加了一个`uppercase`管道,来格式化数据。
|
||||
|
||||
### The Road Ahead
|
||||
|
@ -1165,8 +1204,8 @@ p.
|
|||
我们有了很多用于构建应用的基石。
|
||||
但我们仍然缺少很关键的一块儿:远程数据存取。
|
||||
|
||||
In a forthcoming tutorial chapter,
|
||||
In the next chapter,
|
||||
we’ll replace our mock data with data retrieved from a server using http.
|
||||
|
||||
在即将到来的章节中,我们将从硬编码模拟数据改为使用http服务从服务器获取数据。
|
||||
在下一章,我们将从硬编码模拟数据改为使用http服务从服务器获取数据。
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ code-example(language="bash").
|
|||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
This chaper is an introduction to the Angular http client.
|
||||
This chapter is an introduction to the Angular http client.
|
||||
Please don't be distracted by the details of this backend substitution. Just follow along with the example.
|
||||
|
||||
Learn more later about the *in-memory web api* in the [Http chapter](../guide/server-communication.html#!#in-mem-web-api).
|
||||
|
@ -217,6 +217,11 @@ code-example(language="bash").
|
|||
Loading heroes using `Http` required no changes outside of `HeroService`, but we added a few new features as well.
|
||||
In the following section we will update our components to use our new methods to add, edit and delete heroes.
|
||||
|
||||
Before we can add those methods, we need to initialize some variables with their respective imports.
|
||||
|
||||
+makeExample('toh-6/ts/app/hero-detail.component.ts', 'variables-imports', 'app/hero-detail.component.ts')(format=".")
|
||||
|
||||
:marked
|
||||
### Add/Edit in the *HeroDetailComponent*
|
||||
|
||||
We already have `HeroDetailComponent` for viewing details about a specific hero.
|
||||
|
|
Loading…
Reference in New Issue