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

# Conflicts:
#	.travis.yml
#	public/_includes/_footer.jade
#	public/_includes/_hero-home.jade
#	public/_includes/_next-item.jade
#	public/_includes/_util-fns.jade
#	public/_includes/_version-dropdown.jade
#	public/docs/_examples/package.json
#	public/docs/_examples/quickstart/dart/lib/app_component.dart
#	public/docs/_examples/quickstart/e2e-spec.ts
#	public/docs/_examples/quickstart/js/app/app.component.js
#	public/docs/_examples/quickstart/ts/app/app.component.ts
#	public/docs/_examples/quickstart/ts/index.html
#	public/docs/_examples/toh-5/dart/lib/dashboard_component.html
#	public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart
#	public/docs/dart/latest/_util-fns.jade
#	public/docs/dart/latest/guide/_data.json
#	public/docs/dart/latest/guide/index.jade
#	public/docs/dart/latest/quickstart.jade
#	public/docs/index.jade
#	public/docs/js/latest/quickstart.jade
#	public/docs/ts/_cache/glossary.jade
#	public/docs/ts/_cache/guide/dependency-injection.jade
#	public/docs/ts/_cache/guide/index.jade
#	public/docs/ts/_cache/quickstart.jade
#	public/docs/ts/_cache/tutorial/toh-pt5.jade
#	public/docs/ts/latest/_data.json
#	public/docs/ts/latest/_quickstart_repo.jade
#	public/docs/ts/latest/cli-quickstart.jade
#	public/docs/ts/latest/cookbook/_data.json
#	public/docs/ts/latest/cookbook/a1-a2-quick-reference.jade
#	public/docs/ts/latest/cookbook/aot-compiler.jade
#	public/docs/ts/latest/cookbook/dynamic-form.jade
#	public/docs/ts/latest/glossary.jade
#	public/docs/ts/latest/guide/_data.json
#	public/docs/ts/latest/guide/architecture.jade
#	public/docs/ts/latest/guide/attribute-directives.jade
#	public/docs/ts/latest/guide/browser-support.jade
#	public/docs/ts/latest/guide/change-log.jade
#	public/docs/ts/latest/guide/dependency-injection.jade
#	public/docs/ts/latest/guide/displaying-data.jade
#	public/docs/ts/latest/guide/forms.jade
#	public/docs/ts/latest/guide/index.jade
#	public/docs/ts/latest/guide/lifecycle-hooks.jade
#	public/docs/ts/latest/guide/ngmodule.jade
#	public/docs/ts/latest/guide/npm-packages.jade
#	public/docs/ts/latest/guide/router.jade
#	public/docs/ts/latest/guide/server-communication.jade
#	public/docs/ts/latest/guide/style-guide.jade
#	public/docs/ts/latest/guide/template-syntax.jade
#	public/docs/ts/latest/guide/testing.jade
#	public/docs/ts/latest/guide/typescript-configuration.jade
#	public/docs/ts/latest/guide/upgrade.jade
#	public/docs/ts/latest/guide/user-input.jade
#	public/docs/ts/latest/quickstart.jade
#	public/docs/ts/latest/tutorial/_data.json
#	public/docs/ts/latest/tutorial/index.jade
#	public/docs/ts/latest/tutorial/toh-pt1.jade
#	public/docs/ts/latest/tutorial/toh-pt3.jade
#	public/docs/ts/latest/tutorial/toh-pt5.jade
#	public/docs/ts/latest/tutorial/toh-pt6.jade
#	public/events.jade
#	public/resources/images/devguide/quickstart/hello-angular.png
#	scripts/cache.sh
#	tools/plunker-builder/indexHtmlTranslator.js
This commit is contained in:
rexebin 2016-11-26 21:43:16 +00:00
parent 70606848cc
commit edda524d0d
116 changed files with 2811 additions and 3092 deletions

1
.gitignore vendored
View File

@ -32,3 +32,4 @@ eplnkr.html
protractor-results.txt
link-checker-results.txt
*a2docs.css
/dist

View File

@ -10,7 +10,7 @@ env:
- DBUS_SESSION_BUS_ADDRESS=/dev/null
- DISPLAY=:99.0
- CHROME_BIN=chromium-browser
- LATEST_RELEASE=2.2.0
- LATEST_RELEASE=2.2.3
- TASK_FLAGS="--dgeni-log=warn"
matrix:
- TASK=lint

View File

@ -823,7 +823,8 @@ gulp.task('_harp-compile', function() {
gulp.task('_shred-devguide-examples', ['_shred-clean-devguide', '_copy-example-boilerplate'], function() {
// Split big shredding task into partials 2016-06-14
var examplePaths = globby.sync(EXAMPLES_PATH+'/*/', {ignore: ['**/node_modules', '**/_boilerplate']});
const exPath = path.join(EXAMPLES_PATH, (argv.filter || '') + '*');
var examplePaths = globby.sync(exPath, {ignore: ['**/node_modules', '**/_boilerplate']});
var promise = Promise.resolve(true);
examplePaths.forEach(function (examplePath) {
promise = promise.then(() => docShredder.shredSingleExampleDir(_devguideShredOptions, examplePath));
@ -847,7 +848,7 @@ gulp.task('_shred-clean-devguide-shared-jade', function(cb) {
});
gulp.task('_shred-clean-devguide', function(cb) {
var cleanPath = path.join(_devguideShredOptions.fragmentsDir, '**/*.*')
var cleanPath = path.join(_devguideShredOptions.fragmentsDir, (argv.filter || '*') + '*/*.*')
return del([ cleanPath, '!**/*.ovr.*', '!**/_api/**']);
});

View File

@ -15,12 +15,7 @@
"type": "git",
"url": "https://github.com/angular/angular.io.git"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"license": "MIT",
"bugs": {
"url": ""
},

View File

@ -9,9 +9,4 @@ header(class="background-sky l-relative")
.announcement-bar-slide.clearfix
img(src="/translate/cn/gdd.svg" width="64")
p <strong>2016 Google 开发者大会来啦!(北京 & 上海)</strong>
a(href="http://www.google.cn/intl/zh-CN/events/developerday2016/" target="_blank" class="button md-button") 立即报名
.announcement-bar-slide.clearfix
img(src="/resources/images/logos/anglebrackets/devintersection.png" width="64")
p <strong>参加11月14-16号在阿姆斯特丹召开的DEVintersection</strong>
a(href="https://www.devintersectioneurope.com/#!/" target="_blank" class="button md-button") 立即报名
a(href="http://www.google.cn/intl/zh-CN/events/developerday2016/" target="_blank" class="button md-button") 立即报名

View File

@ -1,5 +1,7 @@
- var currentPage = false
- var nextPage = false
- var hideNextPage = false;
- var data = public.docs[current.path[1]][current.path[2]][current.path[3]]._data
for page, slug in data
@ -7,13 +9,16 @@ for page, slug in data
// CHECK IF CURRENT PAGE IS SET, THEN SET NEXT PAGE
if currentPage
if !nextPage && page.nextable && !page.hide
.l-sub-section
h3 下一步
a.translated-cn(href="/docs/#{current.path[1]}/#{current.path[2]}/#{current.path[3]}/#{slug}.html") #{page.title}
if !hideNextPage
.l-sub-section
h3 下一步
a.translated-cn(href="/docs/#{current.path[1]}/#{current.path[2]}/#{current.path[3]}/#{slug}.html") #{page.title}
//NEXT PAGE HAS NOW BEEN SET
- var nextPage = true
- hideNextPage = page.hideNextPage
// SET CURRENT PAGE FLAG WHEN YOU PASS IT
if current.path[4] == slug
- var currentPage = true

View File

@ -40,7 +40,10 @@
- var _liveLink = 'live link';
- var _ngRepoURL = 'https://github.com/angular/angular';
- var _ngDocRepoURL = 'https://github.com/angular/angular.io';
- var _qsRepo = 'https://github.com/angular/quickstart/blob/master/README.md'
- var _qsRepo = 'https://github.com/angular/quickstart';
- var _qsRepoZip = _qsRepo + '/archive/master.zip';
- var _npm = 'npm';
//- NgModule related
- var _AppModuleVsAppComp = 'AppModule'

View File

@ -1,6 +0,0 @@
# Why the _fragments dir is checked in
Within this repo files generated as a result of shredding the `_examples` dir ( the contents of the `_fragments` dir) are checked in so that we can avoid running the
shredder over the entire `_examples` dir each time someone refreshes the repo ( the `shred-full` gulp task).
The gulp `serve-and-watch` shredder is only a partial shredder. It only shreds files in directories changed during
the current session.

View File

@ -1,6 +1,7 @@
{
"name": "angular-examples",
"version": "1.0.0",
"private": true,
"description": "Example package.json, only contains needed scripts for examples. See _examples/package.json for master package.json.",
"scripts": {
"start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
@ -24,12 +25,7 @@
},
"keywords": [],
"author": "",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"license": "MIT",
"dependencies": {},
"devDependencies": {},
"repository": {}

View File

@ -6,7 +6,7 @@
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [

View File

@ -1,4 +1,4 @@
'use strict'; // necessary for es6 output in node
'use strict'; // necessary for es6 output in node
import { browser, element, by } from 'protractor';
@ -11,7 +11,7 @@ describe('AOT Compilation', function () {
it('should load page and click button', function (done) {
let headingSelector = element.all(by.css('h1')).get(0);
expect(headingSelector.getText()).toEqual('My First Angular App');
expect(headingSelector.getText()).toEqual('Hello Angular');
expect(element.all(by.xpath('//div[text()="Magneta"]')).get(0).isPresent()).toBe(true);
expect(element.all(by.xpath('//div[text()="Bombasto"]')).get(0).isPresent()).toBe(true);

View File

@ -1,6 +1,6 @@
<!-- #docregion -->
<button (click)="toggleHeading()">Toggle Heading</button>
<h1 *ngIf="showHeading">My First Angular App</h1>
<h1 *ngIf="showHeading">Hello Angular</h1>
<h3>List of Heroes</h3>
<div *ngFor="let hero of heroes">{{hero}}</div>

View File

@ -6,7 +6,7 @@
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},

View File

@ -32,6 +32,7 @@ import {
AppComponent,
CarComponent,
HeroesComponent,
// #enddocregion ngmodule
HeroListComponent,
InjectorComponent,
TestComponent,
@ -46,6 +47,7 @@ import {
Provider8Component,
Provider9Component,
Provider10Component,
// #docregion ngmodule
],
// #docregion ngmodule-providers
providers: [
@ -56,4 +58,3 @@ import {
bootstrap: [ AppComponent ]
})
export class AppModule { }
// #enddocregion ngmodule

View File

@ -5,7 +5,7 @@
<div [hidden]="submitted">
<h1>Hero Form</h1>
<!-- #docregion ngSubmit -->
<form *ngIf="active" (ngSubmit)="onSubmit()" #heroForm="ngForm">
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
<!-- #enddocregion ngSubmit -->
<!-- #enddocregion edit-div -->
<div class="form-group">
@ -16,7 +16,7 @@
[(ngModel)]="model.name" name="name"
#name="ngModel" >
<!-- #docregion hidden-error-msg -->
<div [hidden]="name.valid || name.pristine"
<div [hidden]="name.valid || name.pristine"
class="alert alert-danger">
<!-- #enddocregion hidden-error-msg -->
Name is required
@ -34,9 +34,9 @@
<label for="power">Hero Power</label>
<select class="form-control" id="power"
required
[(ngModel)]="model.power" name="power"
[(ngModel)]="model.power" name="power"
#power="ngModel" >
<option *ngFor="let p of powers" [value]="p">{{p}}</option>
<option *ngFor="let pow of powers" [value]="pow">{{pow}}</option>
</select>
<div [hidden]="power.valid || power.pristine" class="alert alert-danger">
Power is required
@ -46,12 +46,18 @@
<!-- #docregion submit-button -->
<button type="submit" class="btn btn-default" [disabled]="!heroForm.form.valid">Submit</button>
<!-- #enddocregion submit-button -->
<!-- #docregion new-hero-button -->
<button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>
<!-- #enddocregion new-hero-button -->
<!-- #docregion new-hero-button-form-reset -->
<button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
<!-- #enddocregion new-hero-button-form-reset -->
<!-- #enddocregion final -->
<i>with</i> reset
&nbsp;&nbsp;
<!-- #docregion new-hero-button-no-reset -->
<button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>
<!-- #enddocregion new-hero-button-no-reset -->
<i>without</i> reset
<!-- NOT SHOWN IN DOCS -->
<div>
<hr>
@ -126,7 +132,7 @@
<div class="form-group">
<label for="power">Hero Power</label>
<select class="form-control" id="power" required>
<option *ngFor="let p of powers" [value]="p">{{p}}</option>
<option *ngFor="let pow of powers" [value]="pow">{{pow}}</option>
</select>
</div>
@ -165,7 +171,7 @@
<select class="form-control" id="power"
required
[(ngModel)]="model.power" name="power">
<option *ngFor="let p of powers" [value]="p">{{p}}</option>
<option *ngFor="let pow of powers" [value]="pow">{{pow}}</option>
</select>
</div>
@ -178,12 +184,12 @@
<!-- EXTRA MATERIAL FOR DOCUMENTATION -->
<hr>
<!-- #docregion ngModel-1-->
<!-- #docregion ngModelName-1 -->
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name">
TODO: remove this: {{model.name}}
<!-- #enddocregion ngModel-1-->
<!-- #enddocregion ngModelName-1 -->
<hr>
<!-- #docregion ngModel-3-->
<input type="text" class="form-control" id="name"
@ -193,16 +199,6 @@
TODO: remove this: {{model.name}}
<!-- #enddocregion ngModel-3-->
<hr>
<!-- #docregion form-active -->
<form *ngIf="active">
<!-- #enddocregion form-active -->
<!-- #docregion ngModelName-1 -->
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name" >
<!-- #enddocregion ngModelName-1 -->
<hr>
<!-- #docregion ngModelName-2 -->
<input type="text" class="form-control" id="name"
required
@ -210,6 +206,5 @@
#spy >
<br>TODO: remove this: {{spy.className}}
<!-- #enddocregion ngModelName-2 -->
</form>
</div>

View File

@ -29,22 +29,10 @@ export class HeroFormComponent {
// #enddocregion first
// #docregion final
// Reset the form with a new hero AND restore 'pristine' class state
// by toggling 'active' flag which causes the form
// to be removed/re-added in a tick via NgIf
// TODO: Workaround until NgForm has a reset method (#6822)
// #docregion new-hero
active = true;
// #docregion new-hero-v1
newHero() {
this.model = new Hero(42, '', '');
// #enddocregion new-hero-v1
this.active = false;
setTimeout(() => this.active = true, 0);
// #docregion new-hero-v1
}
// #enddocregion new-hero-v1
// #enddocregion new-hero
// #enddocregion final
//////// NOT SHOWN IN DOCS ////////

View File

@ -2,7 +2,4 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
// Compiles the module (asynchronously) with the runtime compiler
// which generates a compiled module factory in memory.
// Then bootstraps with that factory, targeting the browser.
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -1,6 +1,7 @@
{
"name": "angular-examples-master",
"version": "1.0.0",
"private": true,
"description": "Master package.json, the superset of all dependencies for all of the _example package.json files. See _boilerplate/package.json for example npm scripts.",
"scripts": {
"protractor": "protractor",
@ -8,12 +9,7 @@
},
"keywords": [],
"author": "",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"license": "MIT",
"dependencies": {
"@angular/common": "~2.2.0",
"@angular/compiler": "~2.2.0",
@ -27,7 +23,7 @@
"@angular/router": "~3.2.0",
"@angular/upgrade": "~2.2.0",
"angular-in-memory-web-api": "~0.1.15",
"angular-in-memory-web-api": "~0.1.16",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.8",
@ -46,7 +42,6 @@
"@types/angular-resource": "^1.5.6",
"@types/angular-route": "^1.3.2",
"@types/angular-sanitize": "^1.3.3",
"@types/core-js": "^0.9.34",
"@types/jasmine": "~2.5.36",
"@types/node": "^6.0.45",
"@types/selenium-webdriver": "^2.53.32",

View File

@ -1,11 +1,9 @@
// #docregion , import
// #docregion
import 'package:angular2/core.dart';
// #enddocregion import
// #docregion metadata
@Component(
selector: 'my-app',
template: '<h1>Hello Angular!</h1>')
// #enddocregion metadata
// #docregion class
class AppComponent {}
template: '<h1>Hello {{name}}</h1>')
class AppComponent {
var name = 'Angular';
}

View File

@ -2,7 +2,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Getting Started</title>
<title>Hello Angular</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- #docregion loaddart -->
@ -11,6 +13,8 @@
<!-- #enddocregion loaddart -->
</head>
<body>
<my-app>Loading...</my-app>
<!-- #docregion my-app-->
<my-app>Loading AppComponent content here ...</my-app>
<!-- #enddocregion my-app-->
</body>
</html>

View File

@ -4,7 +4,7 @@ import { browser, element, by } from 'protractor';
describe('QuickStart E2E Tests', function () {
let expectedMsg = 'Hello Angular!';
let expectedMsg = 'Hello Angular';
beforeEach(function () {
browser.get('');

View File

@ -10,7 +10,7 @@
ng.core.Component({
// #enddocregion ng-namespace-funcs
selector: 'my-app',
template: '<h1>Hello Angular!</h1>'
template: '<h1>Hello Angular</h1>'
// #docregion ng-namespace-funcs
})
// #enddocregion component

View File

@ -5,12 +5,7 @@
"start": "npm run lite",
"lite": "lite-server"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"license": "MIT",
"dependencies": {
"@angular/common": "~2.2.0",
"@angular/compiler": "~2.2.0",

View File

@ -1 +0,0 @@
!systemjs.config.1.js

View File

@ -1,14 +1,8 @@
// #docregion
// #docregion import
import { Component } from '@angular/core';
// #enddocregion import
// #docregion metadata
@Component({
selector: 'my-app',
template: '<h1>Hello Angular!</h1>'
template: `<h1>Hello {{name}}</h1>`
})
// #enddocregion metadata
// #docregion class
export class AppComponent { }
// #enddocregion class
export class AppComponent { name = 'Angular'; }

View File

@ -1,13 +1,11 @@
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -1,9 +1,5 @@
// #docregion
// #docregion import
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
// #enddocregion import
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -1,37 +1,36 @@
<!DOCTYPE html>
<!-- #docregion -->
<html>
<head>
<title>Angular QuickStart</title>
<title>Hello Angular</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<style>
body {color:#369;font-family: Arial,Helvetica,sans-serif;}
</style>
<!-- 1. Load libraries -->
<!-- #docregion libraries -->
<!-- Polyfills for older browsers -->
<!-- #docregion polyfills -->
<!-- Polyfill for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<!-- #enddocregion polyfills -->
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- #enddocregion libraries -->
<!-- 2. Configure SystemJS -->
<!-- #docregion systemjs -->
<!-- #docregion autobootstrap-->
<script> window.autoBootstrap = true; </script>
<!-- #enddocregion autobootstrap-->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
<!-- #enddocregion systemjs -->
</head>
<!-- 3. Display the application -->
<!-- #docregion my-app -->
<body>
<my-app>Loading...</my-app>
<!-- #docregion my-app-->
<my-app>Loading AppComponent content here ...</my-app>
<!-- #enddocregion my-app-->
</body>
<!-- #enddocregion my-app -->
</html>

View File

@ -7,12 +7,7 @@
"tsc": "tsc",
"tsc:w": "tsc -w"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"license": "MIT",
"dependencies": {
"@angular/common": "~2.2.0",
"@angular/compiler": "~2.2.0",

View File

@ -1,9 +1,9 @@
{
"description": "QuickStart",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1].*"
"app/app.component.ts",
"index.html"
],
"open": "app/app.component.ts",
"tags": ["quickstart"]
}
}

View File

@ -6,7 +6,7 @@
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"lib": ["es2015", "dom"],
"noImplicitAny": false
}
}

View File

@ -0,0 +1,17 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by } from 'protractor';
describe('QuickStart E2E Tests', function () {
let expectedMsg = 'Hello Angular';
beforeEach(function () {
browser.get('');
});
it(`should display: ${expectedMsg}`, function () {
expect(element(by.css('h1')).getText()).toEqual(expectedMsg);
});
});

View File

@ -0,0 +1,35 @@
/* tslint:disable:no-unused-variable */
import { AppComponent } from './app.component';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
//////// SPECS /////////////
describe('AppComponent', function () {
let de: DebugElement;
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AppComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css('h1'));
});
it('should create component', () => expect(comp).toBeDefined() );
it('should have expected <h1> text', () => {
fixture.detectChanges();
const h1 = de.nativeElement;
expect(h1.innerText).toMatch(/angular/i,
'<h1> should say something about "Angular"');
});
});

View File

@ -0,0 +1,8 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>`
})
export class AppComponent { name = 'Angular'; }

View File

@ -1,8 +1,11 @@
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule ]
imports: [ BrowserModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

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

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<!-- #docregion -->
<html>
<head>
<title>Hello Angular</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<style>
body {color:#369;font-family: Arial,Helvetica,sans-serif;}
</style>
<!-- Polyfills for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<!-- #docregion my-app-->
<my-app><!-- content managed by Angular --></my-app>
<!-- #enddocregion my-app-->
</body>
</html>

View File

@ -0,0 +1,11 @@
{
"description": "QuickStart Setup",
"files": [
"app/app.component.ts",
"app/app.module.ts",
"app/main.ts",
"index.html"
],
"open": "app/app.component.ts",
"tags": ["quickstart setup"]
}

View File

@ -7,12 +7,7 @@
"lite": "lite-server",
"start": "concurrently \"npm run tsc:w\" \"npm run lite\" "
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"license": "MIT",
"dependencies": {
"angular2": "2.0.0-beta.0",
"systemjs": "0.19.6",

View File

@ -2,7 +2,7 @@
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<!-- #docregion click -->
<a *ngFor="let hero of heroes" [routerLink]="['./HeroDetail', {id: hero.id}]" class="col-1-4">
<a *ngFor="let hero of heroes" [routerLink]="['HeroDetail', {id: hero.id.toString()}]" class="col-1-4">
<!-- #enddocregion click -->
<div class="module hero">
<h4>{{hero.name}}</h4>

View File

@ -37,15 +37,13 @@ class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
Future<Null> ngOnInit() async {
var idString = _routeParams.get('id');
var id = int.parse(idString ?? '', onError: (_) => null);
var _id = _routeParams.get('id');
var id = int.parse(_id ?? '', onError: (_) => null);
if (id != null) hero = await (_heroService.getHero(id));
}
// #enddocregion ngOnInit
// #docregion goBack
void goBack() {
_location.back();
}
void goBack() => _location.back();
// #enddocregion goBack
}

View File

@ -13,7 +13,7 @@ import 'hero_search_component.dart';
selector: 'my-dashboard',
templateUrl: 'dashboard_component.html',
styleUrls: const ['dashboard_component.css'],
directives: const [HeroSearchComponent])
directives: const [HeroSearchComponent, ROUTER_DIRECTIVES])
// #enddocregion search
class DashboardComponent implements OnInit {
List<Hero> heroes;

View File

@ -1,7 +1,7 @@
<!-- #docregion -->
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">
<a *ngFor="let hero of heroes" [routerLink]="['HeroDetail', {id: hero.id.toString()}]" class="col-1-4">
<div class="module hero">
<h4>{{hero.name}}</h4>
</div>

View File

@ -1,10 +1,10 @@
// #docplaster
// #docregion , v2
import 'dart:async';
import 'dart:html';
import 'package:angular2/core.dart';
import 'package:angular2/router.dart';
import 'package:angular2/platform/common.dart';
import 'hero.dart';
import 'hero_service.dart';
@ -18,12 +18,13 @@ class HeroDetailComponent implements OnInit {
Hero hero;
final HeroService _heroService;
final RouteParams _routeParams;
final Location _location;
HeroDetailComponent(this._heroService, this._routeParams);
HeroDetailComponent(this._heroService, this._routeParams, this._location);
Future<Null> ngOnInit() async {
var idString = _routeParams.get('id');
var id = int.parse(idString, onError: (_) => null);
var _id = _routeParams.get('id');
var id = int.parse(_id ?? '', onError: (_) => null);
if (id != null) hero = await (_heroService.getHero(id));
}
@ -34,7 +35,5 @@ class HeroDetailComponent implements OnInit {
}
// #enddocregion save
void goBack() {
window.history.back();
}
void goBack() => _location.back();
}

View File

@ -6,7 +6,7 @@
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [

View File

@ -8,7 +8,7 @@
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [

View File

@ -4,12 +4,7 @@
"version": "0.0.0",
"description": "A tutorial application for AngularJS",
"repository": "https://github.com/angular/angular-phonecat",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"license": "MIT",
"devDependencies": {
"bower": "^1.7.7",
"http-server": "^0.9.0",

View File

@ -20,15 +20,14 @@ export class KeyUpComponent_v1 {
// #enddocregion key-up-component-1-class, key-up-component-1-class-no-type
/*
// #docregion key-up-component-1-class-no-type
// without strong typing
onKey(event:any) {
onKey(event:any) { // without type info
this.values += event.target.value + ' | ';
}
// #enddocregion key-up-component-1-class-no-type
*/
// #docregion key-up-component-1-class
// with strong typing
onKey(event: KeyboardEvent) {
onKey(event: KeyboardEvent) { // with type info
this.values += (<HTMLInputElement>event.target).value + ' | ';
}
// #docregion key-up-component-1-class-no-type
@ -53,23 +52,22 @@ export class KeyUpComponent_v2 {
}
// #enddocregion key-up-component-2
//////////////////////////////////////////
// #docregion key-up-component-3
@Component({
selector: 'key-up3',
template: `
<input #box (keyup.enter)="values=box.value">
<p>{{values}}</p>
<input #box (keyup.enter)="onEnter(box.value)">
<p>{{value}}</p>
`
})
export class KeyUpComponent_v3 {
values = '';
value = '';
onEnter(value: string) { this.value = value; }
}
// #enddocregion key-up-component-3
//////////////////////////////////////////
// #docregion key-up-component-4
@ -77,13 +75,14 @@ export class KeyUpComponent_v3 {
selector: 'key-up4',
template: `
<input #box
(keyup.enter)="values=box.value"
(blur)="values=box.value">
(keyup.enter)="update(box.value)"
(blur)="update(box.value)">
<p>{{values}}</p>
<p>{{value}}</p>
`
})
export class KeyUpComponent_v4 {
values = '';
value = '';
update(value: string) { this.value = value; }
}
// #enddocregion key-up-component-4

View File

@ -7,12 +7,7 @@
"test": "karma start",
"build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"license": "MIT",
"dependencies": {
"@angular/common": "~2.2.0",
"@angular/compiler": "~2.2.0",
@ -27,7 +22,6 @@
"zone.js": "^0.6.25"
},
"devDependencies": {
"@types/core-js": "^0.9.34",
"@types/node": "^6.0.45",
"@types/jasmine": "^2.5.35",
"angular2-template-loader": "^0.4.0",

View File

@ -7,12 +7,19 @@
"banner": "AngularDart is <b>2.0</b>. View the <a href='https://github.com/dart-lang/angular2/blob/master/CHANGELOG.md' target='_blank'>change log</a> to see enhancements, fixes, and breaking changes."
},
"cli-quickstart": {
"icon": "query-builder",
"title": "CLI Quickstart",
"subtitle": "TypeScript",
"description": "Use the CLI tool to quickly build Angular applications",
"hide": true
},
"quickstart": {
"icon": "query-builder",
"title": "Quickstart",
"subtitle": "Dart",
"description": "Get up and running with Angular",
"banner": "This QuickStart guide demonstrates how to build and run a simple Angular application."
"banner": "A quick look at Angular basics"
},
"tutorial": {

View File

@ -22,7 +22,10 @@ include ../../../_includes/_util-fns
- var _ngRepoURL = 'https://github.com/dart-lang/angular2';
//- Don't override this value quite yet:
//- var _ngDocRepoURL = 'https://github.com/dart-lang/site-webdev';
- var _qsRepo = 'https://github.com/angular-examples/quickstart/archive/master.zip'
- var _qsRepo = 'https://github.com/angular-examples/quickstart'
- var _qsRepoZip = _qsRepo + '/archive/master.zip';
- var _npm = 'pub';
//- NgModule related
- var _AppModuleVsAppComp = 'AppComponent'

View File

@ -19,11 +19,13 @@ block annotation-defn
block bootstrap-defn-top
:marked
We launch an Angular application by "bootstrapping" it with the
[bootstrap][bootstrap] method. The `bootstrap` method identifies an
application's top level "root" [Component](#component) and optionally
You launch an Angular application by "bootstrapping" it with the
[bootstrap][bootstrap] method. Bootstraping identifies an
application's top level "root" [component](#component), which is
the first component that is loaded for the application, and optionally
registers service [providers](#provider) with the [dependency injection
system](#dependency-injection).
For more information, see the [Setup](!{docsLatest}/guide/setup.html) page.
[bootstrap]: !{docsLatest}/api/angular2.platform.browser/bootstrap.html
@ -42,17 +44,6 @@ block module-defn
the chapter on "Libraries and Scripts" in the
[Dart Language Specification](https://www.dartlang.org/docs/spec/).
block routing-component-defn
:marked
A [Component](#component) with an attached router.
In most cases, the component became attached to a [router](#router) by means
of a `@RouterConfig` #{decorator} that defined routes to views controlled by this component.
The component's template has a `RouterOutlet` element where it can display views produced by the router.
It likely has anchor tags or buttons with `RouterLink` directives that users can click to navigate.
block append snake-case-defn
:marked
Library and file names are often spelled in snake_case. Examples include:
@ -63,6 +54,6 @@ block zone-defn
Zones are a mechanism for encapsulating and intercepting
a Dart application's asynchronous activity.
To learn more, consult the [zones article][zones].
Learn more about zones in this [article][zones].
[zones]: https://www.dartlang.org/articles/libraries/zones

View File

@ -2,11 +2,29 @@
"index": {
"title": "Documentation Overview",
"navTitle": "Overview",
"description": "How to read and use this documentation",
"intro": "How to read and use this documentation",
"nextable": true,
"basics": true
},
"setup": {
"title": "Setup for local development",
"navTitle": "Setup",
"intro": "Install the Angular QuickStart seed for faster, more efficient development on your machine",
"nextable": true,
"hideNextPage": true,
"basics": true
},
"learning-angular": {
"title": "Learning Angular",
"navTitle": "Learning Angular",
"intro": "A suggested path through the documentation for Angular newcomers",
"nextable": true,
"hideNextPage": true,
"basics": true
},
"architecture": {
"title": "Architecture Overview",
"navTitle": "Architecture",
@ -17,7 +35,7 @@
"displaying-data": {
"title": "Displaying Data",
"intro": "Interpolation and other forms of property binding help us show app data in the UI.",
"intro": "Property binding helps show app data in the UI.",
"nextable": true,
"basics": true
},
@ -63,16 +81,29 @@
"basics": true
},
"glossary": {
"title": "Glossary",
"intro": "Brief definitions of the most important words in the Angular vocabulary",
"basics": true
},
"change-log": {
"hide": true,
"title": "Change Log",
"intro": "An annotated history of recent documentation improvements.",
"basics": true
},
"ngmodule": {
"hide": true,
"title": "Angular Modules (NgModule)",
"intro": "Define application modules with @NgModule",
"hide": true
"intro": "Define application modules with @NgModule"
},
"animations": {
"hide": true,
"title": "Animations",
"intro": "A guide to Angular's animation system.",
"hide": true
"intro": "A guide to Angular's animation system."
},
"attribute-directives": {
@ -90,12 +121,6 @@
"intro": "Learn how to apply CSS styles to components."
},
"glossary": {
"title": "Glossary",
"intro": "Angular中最重要的词汇的简要定义",
"basics": true
},
"hierarchical-dependency-injection": {
"title": "Hierarchical Dependency Injectors",
"navTitle": "Hierarchical Injectors",
@ -104,7 +129,7 @@
"server-communication": {
"title": "HTTP Client",
"intro": "Talk to a remote server with an HTTP Client."
"intro": "Use an HTTP Client to talk to a remote server."
},
"lifecycle-hooks": {
@ -113,9 +138,9 @@
},
"npm-packages": {
"hide": true,
"title": "Npm Packages",
"intro": "Details of the recommended npm packages and the different kinds of package dependencies",
"hide": true
"intro": "Recommended npm packages, and how to specify package dependencies"
},
"pipes": {
@ -125,7 +150,7 @@
"router": {
"title": "Routing & Navigation",
"intro": "Discover the basics of screen navigation with the Angular Component Router."
"intro": "Discover the basics of screen navigation with the Angular Router."
},
"security": {
@ -133,32 +158,38 @@
"intro": "Developing for content security in Angular applications"
},
"setup-systemjs-anatomy": {
"hide": true,
"title": "Setup Anatomy",
"intro": "Inside the local development environment for SystemJS"
},
"structural-directives": {
"title": "Structural Directives",
"intro": "Angular has a powerful template engine that lets us easily manipulate the DOM structure of our elements."
},
"testing": {
"hide": true,
"title": "Testing",
"intro": "Techniques and practices for testing an Angular app",
"hide": true
"intro": "Techniques and practices for testing an Angular app"
},
"typescript-configuration": {
"hide": true,
"title": "TypeScript Configuration",
"intro": "TypeScript configuration for Angular developers",
"hide": true
"intro": "TypeScript configuration for Angular developers"
},
"upgrade": {
"hide": true,
"title": "Upgrading from 1.x",
"intro": "Angular 1 applications can be incrementally upgraded to Angular 2.",
"hide": true
"intro": "Incrementally upgrade an Angular 1 application to Angular 2."
},
"webpack": {
"hide": true,
"title": "Webpack: an introduction",
"intro": "Create your Angular applications with a Webpack based tooling",
"hide": true
"intro": "Create Angular applications with a Webpack based tooling"
}
}

View File

@ -10,6 +10,34 @@ block ctor-syntax
We also leveraged Dart's constructor syntax for declaring parameters and
initializing properties simultaneously.
block register-provider-ngmodule
:marked
Before we do, let's see an example of provider registration during bootstrapping:
+makeExcerpt('app/main.1.ts (discouraged)', 'bootstrap-discouraged', '')
:marked
The injector now knows about our `HeroService`.
An instance of our `HeroService` will be available for injection across our entire application.
Of course we can't help wondering about that comment telling us not to do it this way.
It *will* work. It's just not a best practice.
The bootstrap provider option is intended for configuring and overriding Angular's own
preregistered services, such as its routing support.
The preferred approach is to register application providers in application components.
Because the `HeroService` is used within the *Heroes* feature area &mdash;
and nowhere else &mdash; the ideal place to register it is in the top-level `HeroesComponent`.
block ngmodule-vs-component
:marked
Look at the `providers` part of the `@Component` annotation.
An instance of the `HeroService` is now available for injection in this `HeroesComponent`
and all of its child components.
The `HeroesComponent` itself doesn't happen to need the `HeroService`.
But its child `HeroListComponent` does, so we head there next.
block injectable-not-always-needed-in-ts
//- The [Angular Dart Transformer](https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer)
//- generates static code to replace the use of dart:mirrors. It requires that types be

View File

@ -2,3 +2,4 @@ extends ../../../ts/_cache/guide/index.jade
block includes
include ../_util-fns
- var _angular_io = 'website';

View File

@ -0,0 +1,4 @@
extends ../../../ts/_cache/guide/learning-angular.jade
block includes
include ../_util-fns

View File

@ -0,0 +1,58 @@
extends ../../../ts/_cache/guide/setup.jade
block includes
include ../_util-fns
- var _prereq = 'the Dart SDK';
- var _playground = 'repository';
- var _Install = 'Get';
//- npm/pub commands
- var _install = 'get';
- var _start = 'serve';
block qs-seed
:marked
The <live-example name="quickstart">QuickStart project</live-example> can
conveniently be used to seed new projects. It contains the following core files:
block core-files
+makeTabs(`
quickstart/ts/app/app.component.ts,
quickstart/ts/app/main.ts,
quickstart/ts/index.html,
quickstart/dart/pubspec.yaml,
quickstart/ts/styles.css`,
',,,,quickstart',
`app/app.component.ts,
app/main.ts,
index.html,
pubspec.yaml,
styles.css (excerpt)`)
:marked
These files are organized as follows:
.filetree
.file angular_quickstart
.children
.file lib
.children
.file app_component.dart
.file pubspec.yaml
.file web
.children
.file index.html
.file main.dart
.file styles.css
block install-tooling
:marked
Install the **[Dart SDK](https://www.dartlang.org/downloads/)**,
if not already on your machine, and any tools you like to use with Dart.
The Dart SDK includes tools such as **[pub][pub]**, the Dart package manager.
If you don't have a favorite Dart editor already, try
[WebStorm][WS], which comes with a Dart plugin.
You can also download [Dart plugins for other IDEs and editors][DT].
[WS]: https://confluence.jetbrains.com/display/WI/Getting+started+with+Dart
[DT]: https://www.dartlang.org/tools/
[pub]: https://www.dartlang.org/tools/pub/

View File

@ -2,209 +2,4 @@ extends ../../ts/_cache/quickstart.jade
block includes
include _util-fns
- var _Install = 'Get'
- var _prereq = 'the Dart SDK'
- var _angular_browser_uri = 'angular2/platform/browser.dart'
- var _angular_core_uri = 'angular2/core.dart'
- var _stepInit = 3
block setup-tooling
:marked
Install the **[Dart SDK](https://www.dartlang.org/downloads/)**,
if not already on your machine, and any tools you like to use with Dart.
The Dart SDK includes tools such as **[pub][pub]**, the Dart package manager.
If you don't have a favorite Dart editor already, try
[WebStorm][WS], which comes with a Dart plugin.
You can also download [Dart plugins for other IDEs and editors][DT].
[WS]: https://confluence.jetbrains.com/display/WI/Getting+started+with+Dart
[DT]: https://www.dartlang.org/tools/
[pub]: https://www.dartlang.org/tools/pub/
block package-and-config-files
:marked
In the project folder just created, create a file named
**[pubspec.yaml][pubspec]** with the code below.
This pubspec must specify the **angular2** and **browser**
packages as dependencies, as well as the `angular2` transformer.
It can also specify other packages and transformers for the app to use,
such as [dart_to_js_script_rewriter](https://pub.dartlang.org/packages/dart_to_js_script_rewriter).
[pubspec]: https://www.dartlang.org/tools/pub/pubspec.html
+makeExample('quickstart/dart/pubspec.yaml', null, 'pubspec.yaml')
block install-packages
:marked
From the project folder, run `pub get` to install the angular2 and browser
packages (along with the packages they depend on).
code-example(language="sh" class="code-shell").
pub get
block create-your-app
:marked
Let's create a folder to hold our application and add a super-simple Angular component.
block annotation-fields
:marked
The call to the `@Component` constructor has two
named parameters, `selector` and `template`.
block create-main
p.
Now we need something to tell Angular to load the root component.
Create:
ul
li a #[b folder named #[code web]]
li a <b>file named #[code #[+adjExPath('app/main.ts')]]</b> with the following content:
block commentary-on-index-html
:marked
Note the `<my-app>` tag in the `<body>`, this is *where your app lives!*
block run-app
p.
We have a few options for running our app.
One is to launch a local HTTP server
and then view the app in
<a href="https://www.dartlang.org/tools/dartium/">Dartium</a>.
We can use any web server, such as WebStorm's server
or Python's SimpleHTTPServer.
p.
Another option is to build and serve the app using <code>pub serve</code>,
and then run it by visiting <b><code>http://localhost:8080</code></b> in any modern browser.
Pub serve generates JavaScript on the fly,
which can take a while when first visiting the page.
Pub serve also runs in <b><i>watch mode</i></b>, and will recompile and subsequently serve
any changed assets.
p.
Once the app is running, the browser window should show the following:
block build-app
//- Remove details of building from QS for now. (It is too early for these details.)
if false
.alert.is-important
:marked
If you don't see **Hello Angular!**, make sure you've entered all the code correctly,
in the [proper folders](#wrap-up),
and run `pub get`.
.l-verbose-section#section-angular-run-app
:marked
### Building the app (generating JavaScript)
Before deploying the app, we need to generate JavaScript files.
The `pub build` command makes that easy.
code-example(language="sh" class="code-shell").
&gt; <span class="blk">pub build</span>
Loading source assets...
:marked
The generated JavaScript appears, along with supporting files,
under a directory named `build`.
#angular_transformer
h4 Using the Angular transformer
p.
When generating JavaScript for an Angular app,
be sure to use the Angular transformer.
It analyzes the Dart code,
converting reflection-using code to static code
that Dart's build tools can compile to faster, smaller JavaScript.
The highlighted lines in <code>pubspec.yaml</code>
configure the Angular transformer:
- var stylePattern = { otl: /(transformers:)|(- angular2:)|(entry_points.*$)/gm };
+makeExample('quickstart/dart/pubspec.yaml', null, 'pubspec.yaml', stylePattern)
p.
The <code>entry_points</code> item
identifies the Dart file in our app
that has a <code>main()</code> function.
For more information, see the
<a href="https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer">Angular
transformer wiki page</a>.
.l-sub-section#performance
h3 Performance, the transformer, and Angular libraries
p.
When an app imports <code>bootstrap.dart</code>,
it also gets <code>dart:mirrors</code>,
a reflection library that
causes performance problems when compiled to JavaScript.
Don't worry,
the Angular transformer converts the app's entry points
(<code>entry_points</code> in <code>pubspec.yaml</code>)
so that they don't use mirrors.
#dart_to_js_script_rewriter
h4 Using dart_to_js_script_rewriter
:marked
To improve the app's performance, convert the
HTML file to directly include the generated JavaScript;
one way to do that is with `dart_to_js_script_rewriter`.
To use the rewriter, specify `dart_to_js_script_rewriter` in both
the `dependencies` and `transformers` sections of the pubspec.
- var stylePattern = { otl: /(dart_to_js_script_rewriter.*$)|(- dart_to_js_script_rewriter.*$)|(dependencies:)|(transformers:)/gm };
+makeExample('quickstart/dart/pubspec.yaml', null, 'pubspec.yaml', stylePattern)
.alert.is-important
:marked
The `dart_to_js_script_rewriter` transformer must be
**after** the `angular2` transformer in `pubspec.yaml`.
:marked
For more information, see the docs for
[dart_to_js_script_rewriter](https://pub.dartlang.org/packages/dart_to_js_script_rewriter).
block server-watching
:marked
To see the new version, just reload the page.
.alert.is-important
:marked
Be sure to terminate your local server once you stop working on this app.
block project-file-structure
.filetree
.file angular_quickstart
.children
.file lib
.children
.file app_component.dart
.file pubspec.yaml
.file web
.children
.file index.html
.file main.dart
.file styles.css
.l-verbose-section
:marked
This figure doesn't show generated files and directories.
For example, a `pubspec.lock` file
specifies versions and other identifying information for
the packages that our app depends on.
The `pub build` command creates a `build` directory
containing the JavaScript version of our app.
Pub, IDEs, and other tools often create
other directories and dotfiles.
block project-files
+makeTabs(`
quickstart/ts/app/app.component.ts,
quickstart/ts/app/main.ts,
quickstart/ts/index.html,
quickstart/dart/pubspec.yaml,
quickstart/ts/styles.css`,
',,,,quickstart',
`app/app.component.ts,
app/main.ts,
index.html,
pubspec.yaml,
styles.css (excerpt)`)
- var _on_Plunkr = '';

View File

@ -42,7 +42,7 @@ block angular-router
:marked
The Angular router is a combination of multiple services
(`ROUTER_PROVIDERS`), multiple directives (`ROUTER_DIRECTIVES`), and a
configuration annotation (`RouteConfig`). We'll get them all by importing
configuration annotation (`RouteConfig`). You get them all by importing
the router library:
+makeExcerpt('app/app.component.ts (router imports)', 'import-router')
@ -53,22 +53,22 @@ block angular-router
Not all apps need routing, which is why the Angular *Component Router* is
in a separate, optional library module.
Like for any service, we make router services available to the application
by adding them to the `providers` list. Let's update the `directives` and
Like for any service, you make router services available to the application
by adding them to the `providers` list. Update the `directives` and
`providers` lists to include the router assets:
+makeExcerpt('app/app.component.ts (excerpt)', 'directives-and-providers')
:marked
Notice that we also removed the `HeroesComponent` from the `directives` list.
`AppComponent` no longer shows heroes; that will be the router's job.
We'll soon remove `<my-heroes>` from the template too.
`AppComponent` no longer shows heroes, that will be the router's job,
so you can remove the `HeroesComponent` from the `directives` list.
You'll soon remove `<my-heroes>` from the template too.
block router-config-intro
:marked
### Configure routes and add the router
The `AppComponent` doesn't have a router yet. We'll use the `@RouteConfig`
The `AppComponent` doesn't have a router yet. You'll use the `@RouteConfig`
annotation to simultaneously:
- Assign a router to the component
@ -77,12 +77,12 @@ block router-config-intro
block routerLink
:marked
Notice the `[routerLink]` binding in the anchor tag.
We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to a list
You bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to a list
that tells the router where to navigate when the user clicks the link.
We define a *routing instruction* with a *link parameters list*.
You define a *routing instruction* with a *link parameters list*.
The list only has one element in our little sample, the quoted ***name* of the route** to follow.
Looking back at the route configuration, we confirm that `'Heroes'` is the name of the route to the `HeroesComponent`.
Looking back at the route configuration, confirm that `'Heroes'` is the name of the route to the `HeroesComponent`.
.l-sub-section
:marked
Learn about the *link parameters list*
@ -90,8 +90,8 @@ block routerLink
block redirect-vs-use-as-default
:marked
We don't need a route definition for that. Instead,
we add `useAsDefault: true` to the dashboard *route definition* and the
You don't need a route definition for that. Instead,
add `useAsDefault: true` to the dashboard *route definition* and the
router will display the dashboard when the browser URL doesn't match an existing route.
block templateUrl-path-resolution
@ -105,7 +105,7 @@ block templateUrl-path-resolution
block route-params
:marked
We will no longer receive the hero in a parent component property binding.
You 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`.
@ -116,12 +116,12 @@ block ngOnInit
block extract-id
:marked
Notice how we extract the `id` by calling the `RouteParams.get` method.
Notice how you can extract the `id` by calling the `RouteParams.get` method.
block heroes-component-cleanup
:marked
Because the template for `HeroesComponent` no longer uses `HeroDetailComponent`
directly &mdash; instead using the router to _navigate_ to it &mdash; we can
directly &mdash; instead using the router to _navigate_ to it &mdash; you can
drop the `directives` argument from `@Component` and remove the unused hero detail
import. The revised `@Component` looks like this:
@ -138,7 +138,7 @@ block router-link-active
**The *router-link-active* class**
The Angular Router adds the `router-link-active` class to the HTML navigation element
whose route matches the active route. All we have to do is define the style for it. Sweet!
whose route matches the active route. All you have to do is define the style for it. Sweet!
block file-tree-end
.filetree

View File

@ -10,4 +10,4 @@
h3 Dart
</a> p: <a href="/docs/dart/latest">Angular Dart - 最新版本
p: <a href="/docs/dart/latest">Angular Dart - 最新版本</a>

View File

@ -208,7 +208,7 @@ code-example(format="").
:marked
The `template` property holds the component's companion template.
A template is a form of HTML that tells Angular how to render a view.
Our template is a single line of HTML announcing "Hello Angular!".
Our template is a single line of HTML announcing "Hello Angular".
Now we need something to tell Angular to load this component.

View File

@ -13,7 +13,7 @@ block includes
Most Angular terms are everyday English words
with a specific meaning within the Angular system.
We have gathered here the most prominent terms
This glossary lists the most prominent terms
and a few less familiar ones that have unusual or
unexpected definitions.
@ -23,30 +23,28 @@ block includes
.l-main-section#A
a#aot
:marked
## Ahead-of-Time (AoT) compilation
.l-sub-section
:marked
You can compile Angular applications at build-time.
By compiling your application<span if-docs="ts"> using the compiler-cli, `ngc`</span>, you can bootstrap directly
to a<span if-docs="ts"> module</span> factory, meaning you don't need to include the Angular compiler in your JavaScript bundle.
Ahead-of-time compiled applications also benefit from decreased load time and increased performance.
+ifDocsFor('ts')
a#aot
:marked
## Ahead-of-Time (AoT) Compilation
## Angular module
.l-sub-section
:marked
Angular applications can be compiled by developers at build-time.
By compiling your application using the compiler-cli, `ngc`, you can bootstrap directly
to a Module Factory, meaning you don't need to include the Angular compiler in your javascript bundle.
Ahead-of-time compiled applications also benefit from decreased load time and increased
performance.
Helps you organize an application into cohesive blocks of functionality.
An Angular module identifies the components, directives, and pipes that the application uses along with the list of external Angular modules that the application needs, such as `FormsModule`.
:marked
## Angular Module
.l-sub-section
:marked
Helps us organize an application into cohesive blocks of functionality.
An Angular module identifies the components, directives, and pipes that are used by the application
along with the list of external Angular modules that the application needs, such as `FormsModule`.
Every Angular application has an application root module class. By convention, the class is
called `AppModule` and resides in a file named `app.module.ts`.
Every Angular application has an application root module class. By convention the class is
called `AppModule` and resides in a file named `app.component.ts`.
See the [Angular Module](!{docsLatest}/guide/ngmodule.html) chapter for details and examples.
For details and examples, see the [Angular Module](!{docsLatest}/guide/ngmodule.html) page.
+ifDocsFor('ts|dart')
:marked
@ -57,15 +55,14 @@ block includes
In practice, a synonym for [Decoration](#decorator).
:marked
## Attribute Directive
## Attribute directive
.l-sub-section
:marked
A category of [Directive](#directive) that can listen to and modify the behavior of
A category of [directive](#directive) that can listen to and modify the behavior of
other HTML elements, attributes, properties, and components. They are usually represented
as HTML attributes, hence the name.
The `ngClass` directive for adding and removing CSS class names is a good example of
an Attribute Directive.
A good example of an attribute directive is the `ngClass` directive for adding and removing CSS class names.
.l-main-section#B
@ -74,7 +71,7 @@ block includes
## Barrel
.l-sub-section
:marked
A barrel is a way to *rollup exports* from several ES2015 modules into a single convenience ES2015 module.
A barrel is a way to *rollup exports* from several ES2015 modules into a single convenient ES2015 module.
The barrel itself is an ES2015 module file that re-exports *selected* exports of other ES2015 modules.
Imagine three ES2015 modules in a `heroes` folder:
@ -94,7 +91,7 @@ block includes
import { Hero } from '../heroes/hero.model.ts';
import { HeroService } from '../heroes/hero.service.ts';
:marked
We can add a barrel to the `heroes` folder (called `index` by convention) that exports all of these items:
You can add a barrel to the `heroes` folder (called `index`, by convention) that exports all of these items:
code-example.
export * from './hero.model.ts'; // re-export all of its exports
export * from './hero.service.ts'; // re-export all of its exports
@ -106,13 +103,9 @@ block includes
:marked
The Angular [scoped packages](#scoped-package) each have a barrel named `index`.
That's why we can write this:
+makeExcerpt('quickstart/ts/app/app.component.ts', 'import', '')
.alert.is-important
:marked
Note that you can often achieve this same goal using [Angular modules](#angular-module) instead.
Note that you can often achieve this using [Angular modules](#angular-module) instead.
:marked
## Binding
@ -121,8 +114,8 @@ block includes
Almost always refers to [Data Binding](#data-binding) and the act of
binding an HTML object property to a data object property.
May refer to a [Dependency Injection](#dependency-injection) binding
between a "token" or "key" and a dependency [provider](#provider).
May refer to a [dependency injection](#dependency-injection) binding
between a "token", also referred to as a "key", and a dependency [provider](#provider).
This more rare usage should be clear in context.
:marked
@ -130,11 +123,10 @@ block includes
.l-sub-section
block bootstrap-defn-top
:marked
We launch an Angular application by "bootstrapping" it using the application root Angular module (`AppModule`).
The bootstraping identifies an application's top level "root" [Component](#component), which is the first
component that is loaded for the application. For more information see the [QuickStart](!{docsLatest}/quickstart.html).
You launch an Angular application by "bootstrapping" it using the application root Angular module (`AppModule`). Bootstrapping identifies an application's top level "root" [component](#component), which is the first component that is loaded for the application.
For more information, see the [Setup](!{docsLatest}/guide/setup.html) page.
:marked
One can bootstrap multiple apps in the same `index.html`, each with its own top level root.
You can bootstrap multiple apps in the same `index.html`, each with its own top level root.
.l-main-section#C
:marked
@ -142,31 +134,29 @@ block includes
.l-sub-section
:marked
The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter
_except the first letter which is a lowercase letter_.
_except the first letter, which is lowercase_.
Function, property, and method names are typically spelled in camelCase. Examples include: `square`, `firstName` and `getHeroes`.
Function, property, and method names are typically spelled in camelCase. Examples include: `square`, `firstName` and `getHeroes`. Notice that `square` is an example of how you write a single word in camelCase.
This form is also known as **lower camel case**, to distinguish it from **upper camel case** which we call [PascalCase](#pascalcase).
When we write "camelCase" in this documentation we always mean *lower camel case*.
This form is also known as **lower camel case**, to distinguish it from **upper camel case**, which is [PascalCase](#pascalcase).
When you see "camelCase" in this documentation it always means *lower camel case*.
:marked
## Component
.l-sub-section
:marked
An Angular class responsible for exposing data
to a [View](#view) and handling most of the views display
and user-interaction logic.
An Angular class responsible for exposing data to a [view](#view) and handling most of the views display and user-interaction logic.
The Component is one of the most important building blocks in the Angular system.
It is, in fact, an Angular [Directive](#directive) with a companion [Template](#template).
The *component* is one of the most important building blocks in the Angular system.
It is, in fact, an Angular [directive](#directive) with a companion [template](#template).
The developer applies the `!{_at}Component` !{_decoratorLink} to
You apply the `!{_at}Component` !{_decoratorLink} to
the component class, thereby attaching to the class the essential component metadata
that Angular needs to create a component instance and render it with its template
as a view.
Those familiar with "MVC" and "MVVM" patterns will recognize
the Component in the role of "Controller" or "View Model".
the component in the role of "controller" or "view model".
.l-main-section#D
:marked
@ -181,56 +171,48 @@ block includes
spelled in dash-case.
:marked
## Data Binding
## Data binding
.l-sub-section
:marked
Applications display data values to a user and respond to user
actions (clicks, touches, keystrokes).
We could push application data values into HTML, attach
event listeners, pull changed values from the screen, and
update application data values ... all by hand.
Or we could declare the relationship between an HTML widget
and an application data source ... and let a data binding
Instead of manually pushing application data values into HTML, attaching
event listeners, pulling changed values from the screen, and
updating application data values, you can use data binding by declaring the relationship between an HTML widget and data source and let the
framework handle the details.
Data Binding is that second approach. Angular has a rich
data binding framework with a variety of data binding
Angular has a rich data binding framework with a variety of data binding
operations and supporting declaration syntax.
The many forms of binding include:
* [Interpolation](!{docsLatest}/guide/template-syntax.html#interpolation)
* [Property Binding](!{docsLatest}/guide/template-syntax.html#property-binding)
* [Event Binding](!{docsLatest}/guide/template-syntax.html#event-binding)
* [Attribute Binding](!{docsLatest}/guide/template-syntax.html#attribute-binding)
* [Class Binding](!{docsLatest}/guide/template-syntax.html#class-binding)
* [Style Binding](!{docsLatest}/guide/template-syntax.html#style-binding)
* [Two-way data binding with ngModel](!{docsLatest}/guide/template-syntax.html#ng-model)
Read about the forms of binding in the [Template Syntax](!{docsLatest}/guide/template-syntax.html#data-binding) page:
* [Interpolation](!{docsLatest}/guide/template-syntax.html#interpolation).
* [Property binding](!{docsLatest}/guide/template-syntax.html#property-binding).
* [Event binding](!{docsLatest}/guide/template-syntax.html#event-binding).
* [Attribute binding](!{docsLatest}/guide/template-syntax.html#attribute-binding).
* [Class binding](!{docsLatest}/guide/template-syntax.html#class-binding).
* [Style binding](!{docsLatest}/guide/template-syntax.html#style-binding).
* [Two-way data binding with ngModel](!{docsLatest}/guide/template-syntax.html#ngModel).
Learn more about data binding in the
[Template Syntax](!{docsLatest}/guide/template-syntax.html#data-binding) chapter.
+ifDocsFor('ts|dart')
a#decorator
a#decoration
:marked
## Decorator | Decoration
## Decorator | decoration
.l-sub-section
block decorator-defn
:marked
A Decorator is a **function** that adds metadata to a class, its members (properties, methods) and function arguments.
A decorator is a **function** that adds metadata to a class, its members (properties, methods) and function arguments.
Decorators are a JavaScript language [feature](https://github.com/wycats/javascript-decorators), implemented in TypeScript and proposed for ES2016 (AKA ES7).
We apply a decorator by positioning it
immediately above or to the left of the thing it decorates.
To apply a decorator, position it immediately above or to the left of the thing it decorates.
Angular has its own set of decorators to help it interoperate with our application parts.
Angular has its own set of decorators to help it interoperate with your application parts.
Here is an example of a `@Component` decorator that identifies a
class as an Angular [Component](#component) and an `@Input` decorator applied to a property
of that component.
The elided object argument to the `@Component` decorator would contain the pertinent component metadata.
class as an Angular [component](#component) and an `@Input` decorator applied to the `name` property
of that component. The elided object argument to the `@Component` decorator would contain the pertinent component metadata.
```
@Component({...})
export class AppComponent {
@ -244,77 +226,75 @@ block includes
.alert.is-important
:marked
Always include the parentheses `()` when applying a decorator.
A decorator is a **function** that must be called when applied.
Always include parentheses `()` when applying a decorator.
:marked
## Dependency Injection
## Dependency injection
.l-sub-section
:marked
Dependency Injection is both a design pattern and a mechanism
Dependency injection is both a design pattern and a mechanism
for creating and delivering parts of an application to other
parts of an application that request them.
Angular developers prefer to build applications by defining many simple parts
that each do one thing well and then wire them together at runtime.
that each do one thing well and then wiring them together at runtime.
These parts often rely on other parts. An Angular [Component](#component)
part might rely on a service part to get data or perform a calculation. When a
part "A" relies on another part "B", we say that "A" depends on "B" and
These parts often rely on other parts. An Angular [component](#component)
part might rely on a service part to get data or perform a calculation. When
part "A" relies on another part "B", you say that "A" depends on "B" and
that "B" is a dependency of "A".
We can ask a "Dependency Injection System" to create "A"
You can ask a "dependency injection system" to create "A"
for us and handle all the dependencies.
If "A" needs "B" and "B" needs "C", the system resolves that chain of dependencies
and returns a fully prepared instance of "A".
Angular provides and relies upon its own sophisticated
[Dependency Injection](dependency-injection.html) system
[dependency injection](dependency-injection.html) system
to assemble and run applications by "injecting" application parts
into other application parts where and when needed.
At the core there is an [`Injector`](#injector) that returns dependency values on request.
At the core there is an [`injector`](#injector) that returns dependency values on request.
The expression `injector.get(token)` returns the value associated with the given token.
A token is an Angular type (`OpaqueToken`). We rarely deal with tokens directly; most
A token is an Angular type (`OpaqueToken`). You rarely deal with tokens directly; most
methods accept a class name (`Foo`) or a string ("foo") and Angular converts it
to a token. When we write `injector.get(Foo)`, the injector returns
to a token. When you write `injector.get(Foo)`, the injector returns
the value associated with the token for the `Foo` class, typically an instance of `Foo` itself.
Angular makes similar requests internally during many of its operations
as when it creates a [`Component`](#component) for display.
During many of its operations, Angular makes similar requests internally, such as when it creates a [`component`](#component) for display.
The `Injector` maintains an internal map of tokens to dependency values.
If the `Injector` can't find a value for a given token, it creates
a new value using a `Provider` for that token.
A [Provider](#provider) is a recipe for
A [provider](#provider) is a recipe for
creating new instances of a dependency value associated with a particular token.
An injector can only create a value for a given token if it has
a `Provider` for that token in its internal provider registry.
a `provider` for that token in its internal provider registry.
Registering providers is a critical preparatory step.
Angular registers some of its own providers with every injector.
We can register our own providers.
Learn more in the [Dependency Injection](!{docsLatest}/guide/dependency-injection.html) chapter.
Read more in the [Dependency Injection](!{docsLatest}/guide/dependency-injection.html) page.
:marked
## Directive
.l-sub-section
:marked
An Angular class responsible for creating, re-shaping, and interacting with HTML elements
An Angular class responsible for creating, reshaping, and interacting with HTML elements
in the browser DOM. Directives are Angular's most fundamental feature.
A Directive is almost always associated with an HTML element or attribute.
We often refer to such an element or attribute as the directive itself.
When Angular finds a directive in an HTML template,
it creates the matching directive class instance
and gives that instance control over that portion of the browser DOM.
and gives the instance control over that portion of the browser DOM.
Developers can invent custom HTML markup (e.g., `<my-directive>`) to
associate with their custom directives. They add this custom markup to HTML templates
as if they were writing native HTML. In this way, directives become extensions of
You can invent custom HTML markup (for example, `<my-directive>`) to
associate with your custom directives. You add this custom markup to HTML templates
as if you were writing native HTML. In this way, directives become extensions of
HTML itself.
Directives fall into one of three categories:
@ -324,12 +304,12 @@ block includes
They are the building blocks of an Angular application and the
developer can expect to write a lot of them.
1. [Attribute Directives](#attribute-directive) that can listen to and modify the behavior of
1. [Attribute directives](#attribute-directive) that can listen to and modify the behavior of
other HTML elements, attributes, properties, and components. They are usually represented
as HTML attributes, hence the name.
1. [Structural Directives](#structural-directive), a directive responsible for
shaping or re-shaping HTML layout, typically by adding, removing, or manipulating
1. [Structural directives](#structural-directive), a directive responsible for
shaping or reshaping HTML layout, typically by adding, removing, or manipulating
elements and their children.
.l-main-section#E
@ -342,9 +322,9 @@ block includes
The latest approved version of JavaScript is
[ECMAScript 2016](http://www.ecma-international.org/ecma-262/7.0/)
(AKA "ES2016" or "ES7") and many Angular developers will write their applications
(AKA "ES2016" or "ES7") and many Angular developers write their applications
either in this version of the language or a dialect that strives to be
compatible with it such as [TypeScript](#typesScript).
compatible with it, such as [TypeScript](#typescript).
Most modern browsers today only support the much older "ECMAScript 5" (AKA ES5) standard.
Applications written in ES2016, ES2015 or one of their dialects must be "[transpiled](#transpile)"
@ -356,17 +336,17 @@ block includes
## ES2015
.l-sub-section
:marked
Short hand for "[ECMAScript 2015](#ecmascript=2015)".
Short hand for [ECMAScript](#ecmascript) 2015.
:marked
## ES6
.l-sub-section
:marked
Short hand for "[ECMAScript 2015](#ecmascript=2015)".
Short hand for [ECMAScript](#ecmascript) 2015.
:marked
## ES5
.l-sub-section
:marked
Short hand for "ECMAScript 5", the version of JavaScript run by most modern browsers.
Short hand for [ECMAScript](#ecmascript) 5, the version of JavaScript run by most modern browsers.
See [ECMAScript](#ecmascript).
a#F
@ -386,41 +366,39 @@ a#H
.l-sub-section
:marked
A directive property that can be the ***target*** of a
[Property Binding](!{docsLatest}/guide/template-syntax.html#property-binding).
[property binding](!{docsLatest}/guide/template-syntax.html#property-binding) (explained in detail in the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page).
Data values flow *into* this property from the data source identified
in the template expression to the right of the equal sign.
See the [Template Syntax](!{docsLatest}/guide/template-syntax.html#inputs-outputs) chapter.
See the [Input and output properties](!{docsLatest}/guide/template-syntax.html#inputs-outputs) section of the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page.
:marked
## Interpolation
.l-sub-section
:marked
A form of [Property Data Binding](#data-binding) in which a
A form of [property data binding](#data-binding) in which a
[template expression](#template-expression) between double-curly braces
renders as text. That text may be concatenated with neighboring text
before it is assigned to an element property
or displayed between element tags as in this example.
or displayed between element tags, as in this example.
code-example(language="html" escape="html").
<label>My current hero is {{hero.name}}</label>
:marked
Learn more about interpolation in the
[Template Syntax](!{docsLatest}/guide/template-syntax.html#interpolation) chapter.
Read more about [interpolation](!{docsLatest}/guide/template-syntax.html#interpolation) in the
[Template Syntax](!{docsLatest}/guide/template-syntax.html) page.
.l-main-section#J
+ifDocsFor('ts')
a#jit
a#jit
:marked
## Just-in-Time (JiT) compilation
.l-sub-section
:marked
## Just-in-Time (JiT) Compilation
.l-sub-section
:marked
With Angular _Just-in-time_ bootstrapping you compile your components and modules in the
browser
and launch the application dynamically. This is a good choice during development.
Consider the [Ahead-of-time](#aot) mode for production apps.
With Angular _just-in-time_ bootstrapping you compile your components<span if-docs="ts"> and modules</span> in the browser
and launch the application dynamically. This is a good choice during development.
Consider using the [ahead-of-time](#aot) mode for production apps.
.l-main-section#K
:marked
@ -431,29 +409,29 @@ a#H
.l-main-section#L
:marked
## Lifecycle Hooks
## Lifecycle hooks
.l-sub-section
:marked
[Directives](#directive) and [Components](#component) have a lifecycle
managed by Angular as it creates, updates and destroys them.
[Directives](#directive) and [components](#component) have a lifecycle
managed by Angular as it creates, updates, and destroys them.
Developers can tap into key moments in that lifecycle by implementing
one or more of the "Lifecycle Hook" interfaces.
You can tap into key moments in that lifecycle by implementing
one or more of the lifecycle hook interfaces.
Each interface has a single hook method whose name is the interface name prefixed with `ng`.
For example, the `OnInit` interface has a hook method names `ngOnInit`.
For example, the `OnInit` interface has a hook method named `ngOnInit`.
Angular calls these hook methods in the following order:
* `ngOnChanges` - called when an [input](#input)/[output](#output) binding values change
* `ngOnInit` - after the first `ngOnChanges`
* `ngDoCheck` - developer's custom change detection
* `ngAfterContentInit` - after component content initialized
* `ngAfterContentChecked` - after every check of component content
* `ngAfterViewInit` - after component's view(s) are initialized
* `ngAfterViewChecked` - after every check of a component's view(s)
* `ngOnChanges` - when an [input](#input)/[output](#output) binding value changes.
* `ngOnInit` - after the first `ngOnChanges`.
* `ngDoCheck` - developer's custom change detection.
* `ngAfterContentInit` - after component content initialized.
* `ngAfterContentChecked` - after every check of component content.
* `ngAfterViewInit` - after component's view(s) are initialized.
* `ngAfterViewChecked` - after every check of a component's view(s).
* `ngOnDestroy` - just before the directive is destroyed.
Learn more in the [Lifecycle Hooks](!{docsLatest}/guide/lifecycle-hooks.html) chapter.
Read more in the [Lifecycle Hooks](!{docsLatest}/guide/lifecycle-hooks.html) page.
.l-main-section#M
@ -465,14 +443,13 @@ a#H
:marked
In Angular, there are two types of modules:
- [Angular modules](#angular-module).
See the [Angular Module](!{docsLatest}/guide/ngmodule.html) chapter for details and examples.
- ES2015 modules as described in this section.
For details and examples, see the [Angular Modules](!{docsLatest}/guide/ngmodule.html) page.
- ES2015 modules, as described in this section.
:marked
Angular apps are modular.
In general, we assemble our application from many modules, both the ones we write ourselves
and the ones we acquire from others.
In general, you assemble your application from many modules, both the ones you write and the ones you acquire from others.
A typical module is a cohesive block of code dedicated to a single purpose.
@ -480,21 +457,19 @@ a#H
A module that needs that thing, **imports** it.
The structure of Angular modules and the import/export syntax
is based on the [ES2015](#es2015) module standard
described [here](http://www.2ality.com/2014/09/es6-modules-final.html).
is based on the [ES2015 module standard](http://www.2ality.com/2014/09/es6-modules-final.html).
An application that adheres to this standard requires a module loader to
load modules on request and resolve inter-module dependencies.
load modules on request, and resolve inter-module dependencies.
Angular does not ship with a module loader and does not have a preference
for any particular 3rd party library (although most samples use SystemJS).
Application developers may pick any module library that conforms to the standard
for any particular 3rd party library (although most examples use SystemJS).
You may pick any module library that conforms to the standard.
Modules are typically named after the file in which the exported thing is defined.
The Angular [DatePipe](https://github.com/angular/angular/blob/master/modules/@angular/common/src/pipes/date_pipe.ts)
class belongs to a feature module named `date_pipe` in the file `date_pipe.ts`.
Developers rarely access Angular feature modules directly.
We usually import them from one of the Angular [scoped packages](#scoped-package) such as `@angular/core`.
You rarely access Angular feature modules directly. You usually import them from one of the Angular [scoped packages](#scoped-package) such as `@angular/core`.
a#N
.l-main-section#O
@ -504,8 +479,8 @@ a#N
## Observable
.l-sub-section
:marked
We can think of an observable as an array whose items arrive asynchronously over time.
Observables help us manage asynchronous data, such as data coming from a backend service.
You can think of an observable as an array whose items arrive asynchronously over time.
Observables help you manage asynchronous data, such as data coming from a backend service.
Observables are used within Angular itself, including Angular's event system and its http client service.
To use observables, Angular uses a third-party library called Reactive Extensions (RxJS).
@ -515,12 +490,12 @@ a#N
## Output
.l-sub-section
:marked
A directive property that can be the ***target*** of an
[Event Binding](!{docsLatest}/guide/template-syntax.html#property-binding).
A directive property that can be the ***target*** of
[event binding](!{docsLatest}/guide/template-syntax.html#event-binding).
Events stream *out* of this property to the receiver identified
in the template expression to the right of the equal sign.
See the [Template Syntax](!{docsLatest}/guide/template-syntax.html#inputs-outputs) chapter.
See the [Input and output properties](!{docsLatest}/guide/template-syntax.html#inputs-outputs) section of the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page.
.l-main-section#P
@ -528,20 +503,18 @@ a#N
## PascalCase
.l-sub-section
:marked
The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter.
Class names are typically spelled in PascalCase. Examples include: `Person` and `HeroDetailComponent`.
The practice of writing individual words, compound words, or phrases such that each word or abbreviation begins with a capital letter. Class names are typically spelled in PascalCase. Examples include: `Person` and `HeroDetailComponent`.
This form is also known as **upper camel case**, to distinguish it from **lower camel case** which we simply call [camelCase](#camelcase).
In this documentation, "PascalCase" means *upper camel case* and "camelCase" means *lower camel case*.
This form is also known as **upper camel case** to distinguish it from **lower camel case**, which is simply called [camelCase](#camelcase). In this documentation, "PascalCase" means *upper camel case* and "camelCase" means *lower camel case*.
:marked
## Pipe
.l-sub-section
:marked
An Angular pipe is a function that transforms input values to output values for
display in a [view](#view). We use the `!{_at}Pipe` !{_decoratorLink}
to associate the pipe function with a name. We can then use that
name in our HTML to declaratively transform values on screen.
display in a [view](#view). Use the `!{_at}Pipe` !{_decoratorLink}
to associate the pipe function with a name. You then use that
name in your HTML to declaratively transform values on screen.
Here's an example that uses the built-in `currency` pipe to display
a numeric value in the local currency.
@ -549,24 +522,22 @@ a#N
code-example(language="html" escape="html").
<label>Price: </label>{{product.price | currency}}
:marked
Learn more in the chapter on [pipes](!{docsLatest}/guide/pipes.html) .
Read more in the page on [pipes](!{docsLatest}/guide/pipes.html).
- var _ProviderUrl = docsLatest+'/api/'+(lang == 'dart' ? 'angular2.core' : 'core/index')+'/Provider-class.html'
:marked
## Provider
.l-sub-section
:marked
A [Provider](!{_ProviderUrl}) creates a new instance of a dependency for the
[Dependency Injection](#dependency-injection) system.
It relates a lookup token to code &mdash; sometimes called a "recipe" &mdash;
that can create a dependency value.
A _provider_ creates a new instance of a dependency for the
[dependency injection](#dependency-injection) system.
It relates a lookup token to code&mdash;sometimes called a "recipe"&mdash;that can create a dependency value.
a#Q
.l-main-section#R
+ifDocsFor('ts|js')
:marked
## Reactive Forms
## Reactive forms
.l-sub-section
:marked
A technique for building Angular forms through code in a component.
@ -578,24 +549,22 @@ a#Q
- The template input elements do *not* use `ngModel`.
- The associated Angular directives are all prefixed with `Form` such as `FormGroup`, `FormControl`, and `FormControlName`.
Reactive forms are powerful, flexible, and great for more complex data entry form scenarios, such as dynamic generation
of form controls.
Reactive forms are powerful, flexible, and great for more complex data entry form scenarios such as dynamic generation of form controls.
:marked
## Router
.l-sub-section
:marked
Most applications consist of many screens or [views](#view).
The user navigates among them by clicking links and buttons
and taking other similar actions that cause the application to
The user navigates among them by clicking links and buttons,
and performing other similar actions that cause the application to
replace one view with another.
The Angular [Component Router](!{docsLatest}/guide/router.html) is a richly featured mechanism for configuring
and managing the entire view navigation process including the creation and destruction
The Angular [component router](!{docsLatest}/guide/router.html) is a richly featured mechanism for configuring and managing the entire view navigation process including the creation and destruction
of views.
+ifDocsFor('ts|js')
:marked
In most cases, components becomes attached to a [router](#router) by means
In most cases, components become attached to a [router](#router) by means
of a `RouterConfig` that defines routes to views.
A [routing component's](#routing-component) template has a `RouterOutlet` element
@ -604,31 +573,30 @@ a#Q
Other views in the application likely have anchor tags or buttons with `RouterLink`
directives that users can click to navigate.
See the [Component Router](!{docsLatest}/guide/router.html) chapter to learn more.
For more information, see the [Routing & Navigation](!{docsLatest}/guide/router.html) page.
+ifDocsFor('ts|js')
:marked
## RouterModule
## Router module
.l-sub-section
:marked
A separate [Angular module](#angular-module) that provides the necessary service providers and directives for navigating through application views.
See the [Component Router](!{docsLatest}/guide/router.html) chapter to learn more.
For more information, see the [Routing & Navigation](!{docsLatest}/guide/router.html) page.
:marked
## Routing Component
## Routing component
.l-sub-section
block routing-component-defn
:marked
An Angular [Component](#component) with a RouterOutlet that displays views based on router navigations.
:marked
An Angular [component](#component) with a `RouterOutlet` that displays views based on router navigations.
See the [Component Router](!{docsLatest}/guide/router.html) chapter to learn more.
For more information, see the [Routing & Navigation](!{docsLatest}/guide/router.html) page.
.l-main-section#S
+ifDocsFor('ts|js')
:marked
## Scoped Package
## Scoped package
.l-sub-section
:marked
Angular modules are delivered within *scoped packages* such as `@angular/core`, `@angular/common`, `@angular/platform-browser-dynamic`,
@ -636,9 +604,9 @@ a#Q
A [*scoped package*](https://docs.npmjs.com/misc/scope) is a way to group related *npm* packages.
We import a scoped package the same way we'd import a *normal* package.
You import a scoped package the same way that you'd import a *normal* package.
The only difference, from a consumer perspective,
is that the package name begins with the Angular *scope name*, `@angular`.
is that the *scoped package* name begins with the Angular *scope name*, `@angular`.
+makeExcerpt('architecture/ts/app/app.component.ts', 'import', '')
@ -649,38 +617,34 @@ a#snake-case
.l-sub-section
block snake-case-defn
:marked
The practice of writing compound words or phrases such that each word is separated by an
underscore (`_`). This form is also known as **underscore case**.
The practice of writing compound words or phrases such that an
underscore (`_`) separates one word from the next. This form is also known as **underscore case**.
:marked
## Service
.l-sub-section
:marked
Components are great and all, but what do we do with data or logic that are not associated
with a specific view or that we want to share across components? We build services!
For data or logic that is not associated
with a specific view or that you want to share across components, build services.
Applications often require services such as a hero data service or a logging service.
Our components depend on these services to do the heavy lifting.
A service is a class with a focused purpose.
We often create a service to implement features that are
independent from any specific view,
provide share data or logic across components, or encapsulate external interactions.
provide shared data or logic across components, or encapsulate external interactions.
See the [Services](!{docsLatest}/tutorial/toh-pt4.html) chapter of the tutorial to learn more.
For more information, see the [Services](!{docsLatest}/tutorial/toh-pt4.html) page of the [Tour of Heroes](!{docsLatest}/tutorial/) tutorial.
:marked
## Structural Directive
## Structural directive
.l-sub-section
:marked
A category of [Directive](#directive) that can
shape or re-shape HTML layout, typically by adding, removing, or manipulating
elements and their children.
A category of [directive](#directive) that can
shape or reshape HTML layout, typically by adding, removing, or manipulating
elements and their children; for example, the `ngIf` "conditional element" directive and the `ngFor` "repeater" directive.
The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive are
good examples in this category.
See the [Structural Directives](!{docsLatest}/guide/structural-directives.html) chapter to learn more.
Read more in the [Structural Directives](!{docsLatest}/guide/structural-directives.html) page.
.l-main-section#T
:marked
@ -688,14 +652,13 @@ a#snake-case
.l-sub-section
:marked
A template is a chunk of HTML that Angular uses to render a [view](#view) with
the support and continuing guidance of an Angular [Directive](#directive),
most notably a [Component](#component).
the support and continuing guidance of an Angular [directive](#directive),
most notably a [component](#component).
We write templates in a special [Template Syntax](!{docsLatest}/guide/template-syntax.html).
+ifDocsFor('ts|js')
:marked
## Template-Driven Forms
## Template-driven forms
.l-sub-section
:marked
A technique for building Angular forms using HTML forms and input elements in the view.
@ -704,47 +667,47 @@ a#snake-case
When building template-driven forms:
- The "source of truth" is the template. The validation is defined using attributes on the individual input elements.
- [Two-way binding](#data-binding) with `ngModel` keeps the component model in synchronization with the user's entry into the input elements.
- Behind the scenes, Angular creates a new control for each input element that has a `name` attribute and
two-way binding set up.
- Behind the scenes, Angular creates a new control for each input element, provided you have set up a `name` attribute and two-way binding for each input.
- The associated Angular directives are all prefixed with `ng` such as `ngForm`, `ngModel`, and `ngModelGroup`.
Template-driven forms are convenient, quick, and simple and are a good choice for many basic data entry form scenarios.
Template-driven forms are convenient, quick, and simple. They are a good choice for many basic data entry form scenarios.
Learn how to build template-driven forms
in the [Forms](!{docsLatest}/guide/forms.html) chapter.
Read about how to build template-driven forms
in the [Forms](!{docsLatest}/guide/forms.html) page.
:marked
## Template Expression
## Template expression
.l-sub-section
:marked
An expression is a !{_Lang}-like syntax that Angular evaluates within
a [data binding](#data-binding). Learn how to write template expressions
in the [Template Syntax](!{docsLatest}/guide/template-syntax.html#template-expressions) chapter.
a [data binding](#data-binding).
Read about how to write template expressions
in the [Template Syntax](!{docsLatest}/guide/template-syntax.html#template-expressions) page.
:marked
## Transpile
.l-sub-section
:marked
The process of transforming code written in one form of JavaScript
(e.g., TypeScript) into another form of JavaScript (e.g., [ES5](#es5)).
(for example, TypeScript) into another form of JavaScript (for example, [ES5](#es5)).
:marked
## TypeScript
.l-sub-section
:marked
A version of JavaScript that supports most [ECMAScript 2015](#ecmascript=2015)
language features and many features that may arrive in future versions
of JavaScript such as [Decorators](#decorator).
A version of JavaScript that supports most [ECMAScript 2015](#es2015)
language features such as [decorators](#decorator).
TypeScript is also noteable for its optional typing system which gives
us compile-time type-checking and strong tooling support (e.g. "intellisense",
TypeScript is also noteable for its optional typing system, which gives
us compile-time type checking and strong tooling support (for example, "intellisense",
code completion, refactoring, and intelligent search). Many code editors
and IDEs support TypeScript either natively or with plugins.
TypeScript is the preferred language for Angular development although
we are welcome to write in other JavaScript dialects such as [ES5](#es5).
you can use other JavaScript dialects such as [ES5](#es5).
Learn more about TypeScript on its [website](http://www.typescriptlang.org/).
Read more about TypeScript at [typescript.org](http://www.typescriptlang.org/).
a#U
.l-main-section#V
@ -756,10 +719,10 @@ a#U
A view is a portion of the screen that displays information and responds
to user actions such as clicks, mouse moves, and keystrokes.
Angular renders a view under the control of one or more [Directives](#directive),
especially [Component](#component) directives and their companion [Templates](#template).
The Component plays such a prominent role that we often
find it convenient to refer to a component as a view.
Angular renders a view under the control of one or more [directives](#directive),
especially [component](#component) directives and their companion [templates](#template).
The component plays such a prominent role that it's often
convenient to refer to a component as a view.
Views often contain other views and any view might be loaded and unloaded
dynamically as the user navigates through the application, typically
@ -779,16 +742,16 @@ a#Y
a JavaScript application's asynchronous activity.
The browser DOM and JavaScript have a limited number
of asynchronous activities, activities such as DOM events (e.g., clicks),
of asynchronous activities, activities such as DOM events (for example, clicks),
[promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), and
[XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
calls to remote servers.
Zones intercept all of these activities and give a "zone client" the opportunity
to take action before and after the async activity completes.
to take action before and after the async activity finishes.
Angular runs our application in a zone where it can respond to
asynchronous events by checking for data changes and updating
Angular runs your application in a zone where it can respond to
asynchronous events by checking for data changes, and updating
the information it displays via [data bindings](#data-binding).
Learn more about zones in this

View File

@ -247,43 +247,49 @@ block ctor-syntax
We don't have to create an Angular injector.
Angular creates an application-wide injector for us during the bootstrap process.
+makeExample('dependency-injection/ts/app/main.ts', 'bootstrap', 'app/main.ts (excerpt)')(format='.')
+makeExcerpt('app/main.ts', 'bootstrap')
:marked
We do have to configure the injector by registering the **providers**
that create the services our application requires.
We'll explain what [providers](#providers) are later in this chapter.
Before we do, let's see an example of provider registration during bootstrapping:
+makeExample('dependency-injection/ts/app/main.1.ts', 'bootstrap-discouraged')(format='.')
block register-provider-ngmodule
:marked
We can either register a provider within an [NgModule](ngmodule.html) or in application components
:marked
The injector now knows about our `HeroService`.
An instance of our `HeroService` will be available for injection across our entire application.
### Registering providers in an NgModule
Here's our AppModule where we register a `Logger`, a `UserService`, and an `APP_CONFIG` provider.
Of course we can't help wondering about that comment telling us not to do it this way.
It *will* work. It's just not a best practice.
The bootstrap provider option is intended for configuring and overriding Angular's own
preregistered services, such as its routing support.
The preferred approach is to register application providers in application components.
Because the `HeroService` is used within the *Heroes* feature area &mdash;
and nowhere else &mdash; the ideal place to register it is in the top-level `HeroesComponent`.
- var app_module_ts = 'app/app.module.ts';
+makeExcerpt(app_module_ts + ' (excerpt)', 'ngmodule', app_module_ts, { otl: /(providers:)/ })
//- The preferred approach is to register application providers in application components.
//- Because the `HeroService` is used within the *Heroes* feature area &mdash;
//- and nowhere else &mdash; the ideal place to register it is in the top-level `HeroesComponent`.
:marked
### Registering providers in a component
Here's a revised `HeroesComponent` that registers the `HeroService`.
- var stylePattern = { otl: /(providers:.*),/ };
+makeExample('dependency-injection/ts/app/heroes/heroes.component.1.ts', 'full','app/heroes/heroes.component.ts', stylePattern)(format='.')
- var stylePattern = { otl: /(providers:[^,]+),/ };
+makeExample('app/heroes/heroes.component.1.ts', 'full', 'app/heroes/heroes.component.ts', stylePattern)(format='.')
:marked
Look closely at the `providers` part of the `@Component` metadata.
An instance of the `HeroService` is now available for injection in this `HeroesComponent`
and all of its child components.
block ngmodule-vs-component
:marked
### When to use the NgModule and when an application component?
The `HeroesComponent` itself doesn't happen to need the `HeroService`.
But its child `HeroListComponent` does, so we head there next.
On the one hand, a provider in an NgModule is registered in the root injector. That means that every provider
registered within an NgModule will be accessible in the _entire application_.
On the other hand, a provider registered in an application component is available only on that component and all its children.
We want the `APP_CONFIG` service to be available all across the application, but a `HeroService` is only used within the *Heroes*
feature area and nowhere else.
.l-sub-section
:marked
Also see *"Should I add app-wide providers to the root `AppModule` or the root `AppComponent`?"* in the [NgModule FAQ](../cookbook/ngmodule-faq.html#root-component-or-module).
:marked
### Preparing the HeroListComponent for injection
@ -387,7 +393,6 @@ block ctor-syntax
The constructor now asks for an injected instance of a `Logger` and stores it in a private property called `#{_priv}logger`.
We call that property within our `getHeroes` method when anyone asks for heroes.
//- FIXME refer to Dart API when that page becomes available.
- var injUrl = '../api/core/index/Injectable-decorator.html';
h3#injectable Why @Injectable()?
:marked
@ -462,7 +467,7 @@ block injectable-not-always-needed-in-ts
Our logger service is quite simple:
+makeExample('dependency-injection/ts/app/logger.service.ts', null, 'app/logger.service.ts')
+makeExample('app/logger.service.ts')
block real-logger
//- N/A
@ -470,9 +475,9 @@ block real-logger
:marked
We're likely to need the same logger service everywhere in our application,
so we put it in the project's `#{_appDir}` folder, and
we register it in the `providers` #{_array} of the metadata for our application root component, `AppComponent`.
we register it in the `providers` #{_array} of our application !{_moduleVsComp}, `!{_AppModuleVsAppComp}`.
+makeExcerpt('app/providers.component.ts','providers-logger','app/app.component.ts (excerpt)')
+makeExcerpt('app/providers.component.ts (excerpt)', 'providers-logger','app/app.module.ts')
:marked
If we forget to register the logger, Angular throws an exception when it first looks for the logger:
@ -497,7 +502,7 @@ code-example(format="nocode").
We must register a service *provider* with the injector, or it won't know how to create the service.
Earlier we registered the `Logger` service in the `providers` #{_array} of the metadata for the `AppComponent` like this:
Earlier we registered the `Logger` service in the `providers` #{_array} of the metadata for the `AppModule` like this:
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-logger')
@ -766,7 +771,7 @@ block what-should-we-use-as-token
The TypeScript interface disappears from the generated JavaScript.
There is no interface type information left for Angular to find at runtime.
//- FIXME simplify once APIs are defined for Dart.
//- FIXME update once https://github.com/dart-lang/angular2/issues/16 is addressed.
- var opaquetoken = _docsFor == 'dart' ? '<b>OpaqueToken</b>' : '<a href="../api/core/index/OpaqueToken-class.html"><b>OpaqueToken</b></a>'
:marked
### OpaqueToken
@ -796,9 +801,9 @@ block what-should-we-use-as-token
block dart-map-alternative
:marked
Or we can provide and inject the configuration object in our top-level `AppComponent`.
Or we can provide and inject the configuration object in an ngModule like `AppModule`.
+makeExcerpt('app/app.component.ts','providers')
+makeExcerpt('app/app.module.ts','ngmodule-providers')
#optional
:marked

View File

@ -1,19 +1,6 @@
block includes
include ../_util-fns
figure
img(src="/resources/images/devguide/intro/people.png" alt="Us" align="left" style="width:200px; margin-left:-40px;margin-right:10px")
:marked
This is a practical guide to Angular for experienced programmers who
are building client applications in HTML and #{_Lang}. <br class="l-clear-left">
## Organization
The documentation is divided into major thematic sections, each
a collection of pages devoted to that theme.
block js-alert
- var _angular_io = 'angular.io';
- var __lang = _docsFor || current.path[1] || 'ts';
- var guideData = public.docs[__lang].latest.guide._data;
@ -22,6 +9,19 @@ block js-alert
- if (!guideData[page].basics && !guideData[page].hide) { advancedLandingPage = page; break; }
- }
- var advancedUrl = './' + advancedLandingPage + '.html'
:marked
This page describes the Angular documentation at a high level.
If you're new to Angular, you may want to visit "[Learning Angular](learning-angular.html)" first.
## Themes
The documentation is divided into major thematic sections, each
a collection of pages devoted to that theme.
block js-alert
- var top="vertical-align:top"
table(width="100%")
col(width="15%")
@ -30,19 +30,22 @@ table(width="100%")
td <b><a href="../quickstart.html">QuickStart</a></b>
td
:marked
The foundation for every page and sample in this documentation.
A first taste of Angular<span if-docs="ts"> with zero installation.
Run "Hello World" in an online code editor and start playing with live code</span>.
tr(style=top)
td <b><a href="./">Guide</a></b>
td <b>Guide</b>
td
:marked
The essential ingredients of Angular development.
Learn the Angular basics (you're already here!) like the setup for local development,
displaying data and accepting user input, injecting application services into components,
and building simple forms.
tr(style=top)
td <b><a href="../api">API Reference</a></b>
td <b><a href="../api/">API Reference</a></b>
td
:marked
Authoritative details about each member of the Angular libraries.
Authoritative details about each of the Angular libraries.
tr(style=top)
td <b><a href="../tutorial">Tutorial</a></b>
td <b><a href="../tutorial/">Tutorial</a></b>
td
:marked
A step-by-step, immersive approach to learning Angular that
@ -53,62 +56,37 @@ table(width="100%")
:marked
In-depth analysis of Angular features and development practices.
tr(style=top)
td <b><a href="../cookbook">Cookbook</a></b>
td <b><a href="../cookbook/">Cookbook</a></b>
td
:marked
Recipes for specific application challenges, mostly code snippets with a minimum of exposition.
:marked
## Learning path
You don't have to read the guide straight through. Most pages stand on their own.
For those new to Angular, the recommended learning path runs through the *Guide* section:
1. For the big picture, read the [Architecture](architecture.html) overview.
1. Try [QuickStart](../quickstart.html). QuickStart is the "Hello, World" of Angular.
It shows you how to set up the libraries and tools you'll need to write *any* Angular app.
1. Take the *Tour of Heroes* [tutorial](../tutorial), which picks up where QuickStart leaves off,
and builds a simple data-driven app. The app demonstrates the essential characteristics of a professional application:
a sensible project structure, data binding, master/detail, services, dependency injection, navigation, and remote data access.
1. [Displaying Data](displaying-data.html) explains how to display information on the screen.
1. [User Input](user-input.html) covers how Angular responds to user behavior.
1. [Forms](forms.html) handles user data entry and validation within the UI.
1. [Dependency Injection](dependency-injection.html) is the way to build large, maintainable applications
from small, single-purpose parts.
1. [Template Syntax](template-syntax.html) is a comprehensive study of Angular template HTML.
After reading the above sections, you can skip to any other pages on this site.
A few early pages are written as tutorials and are clearly marked as such.
The rest of the pages highlight key points in code rather than explain each step necessary to build the sample.
You can always get the full source through the #{_liveLink}s.
## Code samples
Each page includes code snippets that you can reuse in your applications.
These snippets are excerpts from a sample application that accompanies the page.
Each page includes code snippets from a sample application that accompanies the page.
You can reuse these snippets in your applications.
Look for a link to a running version of that sample near the top of each page,
Look for a link to a running version of that sample, often near the top of the page,
such as this <live-example name="architecture"></live-example> from the [Architecture](architecture.html) page.
<p if-docs="ts">
The link launches a browser-based code editor where you can inspect, modify, save, and download the code.
</p>
A few early pages are written as tutorials and are clearly marked as such.
The rest of the pages highlight key points in code rather than explain each step necessary to build the sample.
You can always get the full source through the #{_liveLink}.
<span if-docs="ts">
The link launches a browser-based, code editor where you can inspect, modify, save, and download the code.
</span>
## Reference pages
- The [Cheat Sheet](cheatsheet.html) lists Angular syntax for common scenarios.
- The [Glossary](glossary.html) defines terms that Angular developers should know.
- The [API Reference](../api/) is the authority on every public-facing member of the Angular libraries.
* The [Cheat Sheet](cheatsheet.html) lists Angular syntax for common scenarios.
* The [Glossary](glossary.html) defines terms that Angular developers should know.
<li if-docs="ts">The [Change Log](change-log.html) announces what's new and changed in the documentation.</li>
* The [API Reference](../api/) is the authority on every public-facing member of the Angular libraries.
## We welcome feedback!
## Feedback
- Use the [website GitHub repo](!{_ngDocRepoURL}) for **documentation** issues and pull requests.
- Use the [Angular GitHub repo](!{_ngRepoURL}) to report issues with **Angular** itself.
We welcome feedback!
* Use the <a href="!{_ngDocRepoURL}" target="_blank" title="angular docs on github">!{_angular_io} Github repository</a> for **documentation** issues and pull requests.
* Use the <a href="!{_ngRepoURL}" target="_blank" title="angular source on github">Angular Github repository</a> to report issues with **Angular** itself.

View File

@ -0,0 +1,44 @@
block includes
include ../_util-fns
figure
img(src="/resources/images/devguide/intro/people.png" width="200px" height="152px" alt="Us" align="left" style="margin-left:-40px;margin-right:10px" )
:marked
Everyone learns differently.
You don't have to read the documentation straight through. Most pages stand on their own.
Those new to Angular may wish to follow this popular learning path.
<br class="l-clear-left">
:marked
1. [Setup](setup.html "Setup locally withe Quickstart seed") for local Angular development, if you haven't already done so.
1. Take the [*Tour of Heroes* tutorial](../tutorial "Tour of Heroes").
The *Tour of Heroes* takes you step-by-step from [setup](setup.html)
to a full-featured example that demonstrates the essential characteristics of a professional application:
a sensible project structure, data binding, master/detail, services, dependency injection, navigation, and remote data access.
1. <a id="architecture"></a>Read the [Architecture](architecture.html) overview for the big picture.
<li if-docs="ts"><p>
[The Root Module](appmodule.html) introduces the `NgModule` class that tells Angular how to compile and run your application.
</p></li>
1. [Displaying Data](displaying-data.html) shows how data binding puts component property values on screen.
1. [User Input](user-input.html) explains how to respond to user-initiated DOM events.
1. [Forms](forms.html) covers data entry and validation within the UI.
1. [Dependency Injection](dependency-injection.html) is the way to build large, maintainable applications
from small, single-purpose parts.
1. [Template Syntax](template-syntax.html) is a comprehensive study of Angular template HTML.
After reading the above sections, feel free to skip around among the other pages on this site.
.l-sub-section
:marked
### Next Step
Try the [tutorial](../tutorial "Tour of Heroes") if you're ready to start coding or
visit the [Architecture](architecture.html "Basic Concepts") guide if you prefer to learn the basic concepts first.

View File

@ -648,8 +648,9 @@ a#in-mem-web-api
:marked
## Appendix: Tour of Heroes in-memory server
If we only cared to retrieve data, we could tell Angular to get the heroes from a `heroes.json` file like this one:
+makeJson('server-communication/ts/app/heroes.json', null, 'app/heroes.json')(format=".")
If the app only needed to retrieve data, you could get the heroes from a `heroes.json` file:
- var _heroesJsonPath = (_docsFor == 'dart' ? 'web' : 'app') + '/heroes.json';
+makeJson('server-communication/' + _docsFor + '/' + _heroesJsonPath, null, _heroesJsonPath)(format=".")
.l-sub-section
:marked
We wrap the heroes array in an object with a `data` property for the same reason that a data server does:

View File

@ -0,0 +1,180 @@
block includes
include ../_util-fns
- var _prereq = 'node and npm';
- var _playground = 'playground';
- var _Install = 'Install';
//- npm commands
- var _install = 'install';
- var _start = 'start';
a#develop-locally
:marked
## Setup a local development environment
<span if-docs="ts">
The <live-example name=quickstart>QuickStart live-coding</live-example> example is an Angular _playground_.
It's not where you'd develop a real application.
You [should develop locally](#why-locally "Why develop locally") on your own machine ... and that's also how we think you should learn Angular.
</span>
Setting up a new project on your machine is quick and easy with the **QuickStart seed**,
maintained [on github](!{_qsRepo} "Install the github QuickStart repo").
Make sure you have [!{_prereq} installed](#install-prerequisites "What if you don't have !{_prereq}?").
Then ...
1. Create a project folder (you can call it `quickstart` and rename it later).
1. [Clone](#clone "Clone it from github") or [download](#download "download it from github") the **QuickStart seed** into your project folder.
1. !{_Install} [!{_npm}](#install-prerequisites "What if you don't have !{_prereq}?") packages.
1. Run `!{_npm} !{_start}` to launch the sample application.
a#clone
:marked
### Clone
Perform the _clone-to-launch_ steps with these terminal commands.
code-example(language="sh" class="code-shell").
git clone !{_qsRepo}.git quickstart
cd quickstart
!{_npm} !{_install}
!{_npm} !{_start}
a#download
:marked
### Download
<a href="!{_qsRepoZip}" title="Download the QuickStart seed repository">Download the QuickStart seed</a>
and unzip it into your project folder. Then perform the remaining steps with these terminal commands.
code-example(language="sh" class="code-shell").
cd quickstart
!{_npm} !{_install}
!{_npm} !{_start}
.l-main-section#seed
:marked
## What's in the QuickStart seed?
block qs-seed
:marked
The **QuickStart seed** contains the same application as the QuickStart playground
and even has <live-example>its own _playground_</live-example>
that accomodates development of richer examples in a live coding environment.
But it's true purpose is to provide a solid foundation for _local_ development.
Consequently, there are _many more files_ in the project folder on your machine,
most of which you can [learn about later](setup-systemjs-anatomy.html "Setup Anatomy").
block core-files
:marked
Focus on the following three TypeScript (`.ts`) files in the **`/app`** folder.
.filetree
.file app
.children
.file app.component.ts
.file app.module.ts
.file main.ts
+makeTabs(`
setup/ts/app/app.component.ts,
setup/ts/app/app.module.ts,
setup/ts/app/main.ts
`, '', `
app/app.component.ts,
app/app.module.ts,
app/main.ts
`)(format='.')
:marked
All guides and cookbooks have _at least these core files_. Each file has a distinct purpose and evolves independently as the application grows.
style td, th {vertical-align: top}
table(width="100%")
col(width="20%")
col(width="80%")
tr
th File
th Purpose
tr
td <ngio-ex>app.component.ts</ngio-ex>
td
:marked
Defines the same `AppComponent` as the one in the QuickStart !{_playground}.
It is the **root** component of what will become a tree of nested components
as the application evolves.
tr(if-docs="ts")
td <code>app.module.ts</code>
td
:marked
Defines `AppModule`, the [root module](appmodule.html "AppModule: the root module") that tells Angular how to assemble the application.
Right now it declares only the `AppComponent`.
Soon there will be more components to declare.
tr
td <ngio-ex>main.ts</ngio-ex>
td
:marked
Compiles the application with the [JiT compiler](../glossary.html#jit)
and [bootstraps](appmodule.html#main "bootstrap the application") the application to run in the browser.
That's a reasonable choice for the development of most projects and
it's the only viable choice for a sample running in a _live-coding_ environment like Plunker.
You'll learn about alternative compiling and deployment options later in the documentation.
.l-sub-section
:marked
### Next Step
If you're new to Angular, we recommend staying on the [learning path](learning-angular.html).
br
br
a#install-prerequisites
.l-main-section
:marked
## Appendix: !{_prereq}
block install-tooling
:marked
Node.js and npm are essential to modern web development with Angular and other platforms.
Node powers client development and build tools.
The _npm_ package manager, itself a _node_ application, installs JavaScript libraries.
<a href="https://docs.npmjs.com/getting-started/installing-node" target="_blank" title="Installing Node.js and updating npm">
Get them now</a> if they're not already installed on your machine.
**Verify that you are running node `v4.x.x` or higher and npm `3.x.x` or higher**
by running the commands `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors.
We recommend [nvm](https://github.com/creationix/nvm) for managing multiple versions of node and npm.
You may need [nvm](https://github.com/creationix/nvm) if you already have projects running on your machine that
use other versions of node and npm.
+ifDocsFor('ts')
a#why-locally
.l-main-section
:marked
## Appendix: Why develop locally
<live-example>Live coding</live-example> in the browser is a great way to explore Angular.
Links on almost every documentation page open completed samples in the browser.
You can play with the sample code, share your changes with friends, and download and run the code on your own machine.
The [QuickStart](../quickstart.html "Angular QuickStart Playground") shows just the `AppComponent` file.
It creates the equivalent of `app.module.ts` and `main.ts` internally _for the playground only_.
so the reader can discover Angular without distraction.
The other samples are based on the QuickStart seed.
As much fun as this is ...
* you can't ship your app in plunker
* you aren't always online when writing code
* transpiling TypeScript in the browser is slow
* the type support, refactoring, and code completion only work in your local IDE
Use the <live-example><i>live coding</i></live-example> environment as a _playground_,
a place to try the documentation samples and experiment on your own.
It's the perfect place to reproduce a bug when you want to
<a href="https://github.com/angular/angular.io/issues/new" target="_blank" title="File a documentation issue">file a documentation issue</a> or
<a href="https://github.com/angular/angular/issues/new" target="_blank" title="File an Angular issue">file an issue with Angular itself</a>.
For real development, we strongly recommend [developing locally](#develop-locally).

View File

@ -1,382 +1,45 @@
block includes
include _util-fns
- var _Install = 'Install'
- var _prereq = 'Node.js and npm'
- var _angular_browser_uri = '@angular/platform-browser-dynamic'
- var _angular_core_uri = '@angular/core'
- var _stepInit = 4 // Step # after NgModule step
- var _quickstartSrcURL='https://github.com/angular/quickstart/blob/master/README.md'
- var _on_Plunkr = 'on Plunkr';
//- TS/Dart shared step counter
- var step = _stepInit
:marked
Angular applications are made of _components_.
A _component_ is the combination of an HTML template and a component class that controls a portion of the screen. Here is an example of a component that displays a simple string:
+makeExample('app/app.component.ts')(format='.')
:marked
You can try this out without installing anything. Open the <live-example>QuickStart example !{_on_Plunkr}</live-example> in another tab
and follow along.
Every component begins with an `@Component` [!{_decorator}](glossary.html#!{_decorator} '"!{_decorator}" explained')
<span if-docs="ts">function</span> that
<span if-docs="ts">takes a _metadata_ object. The metadata object</span> describes how the HTML template and component class work together.
The `selector` property tells Angular to display the component inside a custom `<my-app>` tag in the `index.html`.
+makeExample('index.html','my-app','index.html (inside <body>)')(format='.')
:marked
The `template` property defines a message inside an `<h1>` header.
The message starts with "Hello" and ends with `{{name}}`
which is an Angular [interpolation binding](guide/displaying-data.html) expression.
At runtime, Angular replaces `{{name}}` with the value of the component's `name` property.
In the example, change the component class's `name` property from `'Angular'` to `'World'` and see what happens.
Interpolation binding is one of many Angular features you'll discover in this documentation.
+ifDocsFor('ts')
aside.is-right
:marked
The live example link opens the finished application in
<a href="http://plnkr.co/" title="Plunker" target="_blank">Plunker</a> so that you can interact
with the code. You'll find live examples at the start of most sections.
:marked
The QuickStart application has the structure of a real-world Angular application and
displays the simple message:
figure.image-display
img(src='/resources/images/devguide/quickstart/hello-angular.png' alt="Output of QuickStart app")
:marked
**Try it out**. Here's a link to a <live-example></live-example>.
+ifDocsFor('ts')
:marked
You can also <a href="!{_quickstartSrcURL}" target="_blank">
clone the entire QuickStart application</a> from GitHub.
h1 Build this application!
:marked
- [Prerequisite](#prereq): Install #{_prereq}.
- [Step 1](#create-and-configure): Create and configure the project.
- [Step 2](#ngmodule): Create your application.
<li if-docs="ts">[Step 3](#root-component): Create a component and add it to your application.</li>
- [Step !{step++}](#main): Start up your application.
- [Step !{step++}](#index): Define the web page that hosts the application.
- [Step !{step++}](#build-and-run): Build and run the application.
- [Step !{step++}](#make-changes): Make some live changes.
- [Wrap up and Next Steps](#wrap-up)
- var step = _stepInit // reinitialize step counter for headers to come
.l-main-section#prereq
h2 Prerequisite: Install #{_prereq}
block setup-tooling
:marked
If Node.js and npm aren't already on your machine, <a href="http://blog.npmjs.org/post/85484771375/how-to-install-npm"
target="_blank">install them</a>. Our examples require node **v4.x.x** or higher and
npm **3.x.x** or higher. To check which version you are using, run `node -v` and `npm -v`
in a terminal window.
.l-main-section
h2#create-and-configure Step 1: Create and configure the project
- var _package_and_config_files = _docsFor == 'dart' ? 'pubspec.yaml' : 'configuration files'
:marked
In this step you will:
* [Create the project folder](#create-the-project-folder)
* [Create #{_package_and_config_files}](#add-config-files)
* [#{_Install} packages](#install-packages)
h3 Create the project folder
:marked
Using a terminal window, create a directory for the project, and change into this
directory.
- var _ = _docsFor == 'dart' ? '_' : '-';
code-example(language="sh" class="code-shell").
mkdir angular!{_}quickstart
cd angular!{_}quickstart
h3#add-config-files Create #{_package_and_config_files}
block package-and-config-files
- var _tsconfigUri = 'guide/typescript-configuration.html#tsconfig'
p Our typical Angular project needs several configuration files:
ul
li.
#[b package.json] identifies npm package dependencies for the project.
li.
#[b tsconfig.json] defines how the TypeScript compiler generates JavaScript from the project's
files.
li.
#[b systemjs.config.js] provides information to a module loader about where to find
application modules, and registers all the necessary packages. It also
contains other packages that will be needed by later documentation examples.
p.
Create each of these files in your project directory. Populate them by pasting in text from
the tabs in the example box below.
a#config-files
+makeTabs(`
quickstart/ts/package.1.json,
quickstart/ts/tsconfig.1.json,
quickstart/ts/systemjs.config.1.js
`, '', `
package.json,
tsconfig.json,
systemjs.config.js
`)
p.
Learn more about these configuration files in the
#[a(href="guide/npm-packages.html") Npm Package Configuration] guide and the
#[a(href="#{_tsconfigUri}") TypeScript Configuration] guide.
A detailed discussion of module loading is beyond the scope of this guide.
.callout.is-helpful
header SystemJS or Webpack?
header A word about TypeScript
p.
Although we use SystemJS for illustrative purposes here, it's only one option for loading
modules. Use the module loader that you prefer. For Webpack and Angular, see <a
href="guide/webpack.html" >
Webpack: an Introduction</a>. Or, learn more about SystemJS configuration in general <a href="https://github.com/systemjs/systemjs/blob/master/docs/config-api.md" target="_blank">here</a>.
This example is written in <a href="http://www.typescriptlang.org/" target="_blank" title="TypeScript">TypeScript</a>, a superset of JavaScript. Angular
uses TypeScript because its types make it easy to support developer productivity with tooling. You can also write Angular code in JavaScript; <a href="cookbook/ts-to-js.html">this guide</a> explains how.
h3#install-packages #{_Install} packages
block install-packages
:marked
Using npm from the command line, install the packages listed in `package.json` with the command:
code-example(language="sh" class="code-shell").
npm install
:marked
Error messages&mdash;in red&mdash;might appear during the install, and you might see `npm WARN` messages. As long as there are no `npm ERR!` messages at the end, you can assume success.
:marked
You should now have the following structure:
.filetree
.file angular-quickstart
.children
.file node_modules ...
.file package.json
.file systemjs.config.js
.file tsconfig.json
:marked
You're now ready to write some code!
.l-main-section
h2#ngmodule Step 2: Create your application
block create-your-app
:marked
You compose Angular applications into closely related blocks of functionality with
[NgModules](guide/ngmodule.html). Angular itself is split into separate Angular Modules. This
makes it possible for you to keep payload size small by only importing the parts of Angular
that your application needs.
Every Angular application has at least one module: the _root module_, named `AppModule` here.
:marked
**Create #{_an} #{_appDir} subfolder** off the project root directory:
code-example.code-shell.
mkdir #{_appDir}
+ifDocsFor('ts')
:marked
Create the file `app/app.module.ts` with the following content:
+makeExample('app/app.module.1.ts')(format='.')
:marked
This is the entry point to your application.
Since the QuickStart application is a web application that runs in a browser, your root module
needs to import the
[`BrowserModule`](../latest/api/platform-browser/index/BrowserModule-class.html)
from `@angular/platform-browser` to the `imports` array.
This is the smallest amount of Angular that is needed for a minimal application to run in the
browser.
The QuickStart application doesn't do anything else, so you don't need any other modules. In a real
application, you'd likely import [`FormsModule`](../latest/api/forms/index/FormsModule-class.html)
as well as [`RouterModule`](../latest/api/router/index/RouterModule-class.html) and
[`HttpModule`](../latest/api/http/index/HttpModule-class.html). These are introduced in the
[Tour of Heroes Tutorial](./tutorial/).
.l-main-section
h2#root-component Step 3: Create a component and add it to your application
:marked
Every Angular application has at least one component: the _root component_, named `AppComponent`
here.
Components are the basic building blocks of Angular applications. A component controls a portion
of the screen&mdash;a *view*&mdash;through its associated template.
#app-component
:marked
**Create the component file** <span ngio-ex>app/app.component.ts</span> with the following content:
+makeExample('app/app.component.ts')
- var _decorator_function = _docsFor == 'dart' ? 'annotation' : 'decorator function';
:marked
The QuickStart application has the same essential structure as any other Angular component:
* **An import statement**. Importing gives your component access to
Angular's core [`@Component` !{_decorator_function}](./api/core/index/Component-decorator.html).
* **A @Component #{_decorator}** that associates *metadata* with the
`AppComponent` component class:
- a *selector* that specifies a simple CSS selector for an HTML element that represents
the component.
- a *template* that tells Angular how to render the component's view.
* **A component class** that controls the appearance and behavior of a view
through its template. Here, you only have the root component, `AppComponent`. Since you don't
need any application logic in the simple QuickStart example, it's empty.
+ifDocsFor('ts')
:marked
You *export* the `AppComponent` class so that you can *import* it into the application that you
just created.
Edit the file `app/app.module.ts` to import your new `AppComponent` and add it in the
declarations and bootstrap fields in the `NgModule` decorator:
+makeExample('app/app.module.ts')
.l-main-section
h2#main Step !{step++}: Start up your application
block create-main
:marked
Now you need to tell Angular to start up your application.
Create the file `app/main.ts` with the following content:
+makeExample('app/main.ts')
- var _pBD_bootstrapModule = _docsFor == 'dart' ? _bootstrapModule : 'platformBrowserDynamic().bootstrapModule'
:marked
This code initializes the platform that your application runs in, then uses the platform to
bootstrap your `!{_AppModuleVsAppComp}`.
### Why create separate *<span ngio-ex>main.ts</span>*<span if-docs="ts">, app module</span> and app component files?
App bootstrapping is a separate concern from<span if-docs="ts"> creating a module or</span>
presenting a view. Testing the component is much easier if it doesn't also try to run the entire application.
.callout.is-helpful
header Bootstrapping is platform-specific
:marked
Because the QuickStart application runs directly in the browser, `main.ts` imports the
`!{_platformBrowserDynamicVsBootStrap}` function from `#{_angular_browser_uri}`, not
`#{_angular_core_uri}`. On a mobile device, you might load a !{_moduleVsComp} with
[Apache Cordova](https://cordova.apache.org/) or
[NativeScript](https://www.nativescript.org/), using a bootstrap function that's specific
to that platform.
.l-main-section
h2#index Step !{step++}: Define the web page that hosts the application
:marked
In the *#{_indexHtmlDir}* folder,
create an `index.html` file and paste the following lines into it:
+makeExample('index.html')
block commentary-on-index-html
:marked
The noteworthy sections here are:
* JavaScript libraries: `core-js` polyfills for older browsers, the `zone.js` and
`reflect-metadata` libraries needed by Angular, and the `SystemJS` library for module loading.
* Configuration file for `SystemJS`, and a script
where you import and run the `app` module which refers to the `main` file that you just
wrote.
* The `<my-app>` tag in the `<body>` which is *where your app lives!*
:marked
### Add some style
Styles aren't essential, but they're nice, and `index.html` assumes that you have
a stylesheet called `styles.css`.
Create a `styles.css` file in the *#{_indexHtmlDir}* folder, and start styling,
perhaps with the minimal styles shown below.
+makeExcerpt('styles.css (excerpt)', 'quickstart')
.callout.is-helpful
:marked
For the full set of master styles used by the documentation samples,
see [styles.css](https://github.com/angular/angular.io/blob/master/public/docs/_examples/_boilerplate/styles.css).
.l-main-section#build-and-run
h2 Step !{step++}: Build and run the application
block run-app
:marked
Open a terminal window and enter this command:
code-example.code-shell.
npm start
aside.is-right
.l-sub-section
:marked
[Read more](https://github.com/angular/quickstart/blob/master/README.md#npm-scripts) about
other useful npm scripts included in this example's `package.json`.
### Next step
:marked
That command runs the following two parallel node processes:
* The TypeScript compiler in watch mode.
* A static file server called _lite-server_ that loads `index.html` in a browser
and refreshes the browser when application files change.
To learn how to write a real application, your next step is to set up a local development
environment and begin exploring with code. The [**Developer Guide**](guide/index.html)
shows you how.
In a few moments, a browser tab should open and display the following:
figure.image-display
img(src='/resources/images/devguide/quickstart/hello-angular.png' alt="Output of QuickStart app")
block build-app
//- Nothing for ts.
.l-main-section#make-changes
h2 Step !{step++}: Make some live changes
:marked
Try changing the message in <span ngio-ex>app/app.component.ts</span> to "Hello Again Angular!".
block server-watching
:marked
The TypeScript compiler and `lite-server` will detect your change, recompile the TypeScript into JavaScript,
refresh the browser, and display your revised message.
Close the terminal window when you're done to terminate both the compiler and the server.
.l-main-section
h2#wrap-up Wrap up and next steps
:marked
The final project folder structure looks like this:
block project-file-structure
.filetree
.file angular-quickstart
.children
.file app
.children
.file app.component.ts
.file app.module.ts
.file main.ts
.file node_modules ...
.file index.html
.file package.json
.file styles.css
.file systemjs.config.js
.file tsconfig.json
:marked
To see the file contents, open the <live-example></live-example>.
.l-main-section
:marked
## What next?
This first application doesn't do much. It's basically "Hello, World" for Angular.
You wrote a little Angular component, created a simple `index.html`, and launched with a
static file server.
+ifDocsFor('ts')
:marked
You also created the basic application setup that you'll re-use for other
sections in this guide. From here, the changes you'll make in the
`package.json` or `index.html` files are only minor updates to add libraries or some css
stylesheets. You also won't need to revisit module loading again.
:marked
To take the next step and build a small application that demonstrates real features that you can
build with Angular, carry on to the [Tour of Heroes tutorial](./tutorial)!

View File

@ -79,5 +79,3 @@ figure.image-display
met in countless applications. Everything has a reason.
And well meet many of the core fundamentals of Angular along the way.
[Let's get started!](./toh-pt1.html)

View File

@ -3,7 +3,6 @@
block includes
include ../_util-fns
- var _appRoutingTsVsAppComp = 'app.module.ts'
- var _declsVsDirectives = 'declarations'
- var _RoutesVsAtRouteConfig = 'Routes'
- var _RouterModuleVsRouterDirectives = 'RouterModule'
- var _redirectTo = 'redirectTo'
@ -511,10 +510,16 @@ block route-params
+makeExcerpt('app/hero-detail.component.ts (constructor)', 'ctor')
+ifDocsFor('ts')
:marked
Also import the `switchMap` operator to use later with the route parameters `Observable`.
+makeExcerpt('app/hero-detail.component.ts (switchMap import)', 'rxjs-import')
:marked
We tell the class that we want to implement the `OnInit` interface.
+makeExcerpt('app/hero-detail.component.ts', 'implement', '')(format=".")
+makeExcerpt('app/hero-detail.component.ts', 'implement', '')
block ngOnInit
:marked
@ -526,14 +531,27 @@ block ngOnInit
block extract-id
:marked
Notice how we extract the `id` by calling the `forEach` method
which will deliver our !{_array} of route parameters.
Note how the `switchMap` operator maps the id in the observable route parameters
to a new `Observable`, the result of the `HeroService.getHero` method.
If the user re-navigates to this component while a getHero request is still inflight,
switchMap cancels that old request before calling `HeroService.getHero` again.
- var _str2int = _docsFor == 'dart' ? '<code>int.parse</code> static method' : 'JavaScript (+) operator'
:marked
The hero `id` is a number. Route parameters are *always strings*.
So we convert the route parameter value to a number with the !{_str2int}.
+ifDocsFor('ts')
.l-sub-section
:marked
### Do I need to unsubscribe?
The `Router` manages the [observables](../guide/router.html#activated-route) it provides and localizes
the subscriptions. The subscriptions are cleaned up when the component is destroyed, protecting against
memory leaks, so we don't need to _unsubscribe_ from the route params `Observable`.
:marked
### Add *HeroService.getHero*
The problem with this bit of code is that `HeroService` doesn't have a `getHero` method!
@ -654,16 +672,16 @@ block extract-id
+makeExample('app/app-routing.module.ts')
:marked
Noteworthy points, typical of _Routing Modules_:
* Pull the routes into a variable. You might export it in future and it clarifies the _Routing Module_ pattern.
* Pulls the routes into a variable. You might export it in future and it clarifies the _Routing Module_ pattern.
* Add `RouterModule.forRoot(routes)` to `imports`.
* Adds `RouterModule.forRoot(routes)` to `imports`.
* Add `RouterModule` to `exports` so that the components in the companion module have access to Router declarables
* Adds `RouterModule` to `exports` so that the components in the companion module have access to Router declarables
such as `RouterLink` and `RouterOutlet`.
* No `declarations`! Declarations are the responsibility of the companion module.
* Add module `providers` for guard services if you have them; there are none in this example.
* Adds module `providers` for guard services if you have them; there are none in this example.
### Update _AppModule_
@ -676,7 +694,7 @@ block extract-id
null,
`app/app.module.ts (after), app/app.module.ts (before)`)
:marked
It's simpler and focused on indentifying the key pieces of the application.
It's simpler and focused on identifying the key pieces of the application.
.l-main-section
:marked
@ -870,9 +888,7 @@ block css-files
We can also create styles at the *application level* outside of any component.
Our designers provided some basic styles to apply to elements across the entire app.
These correspond to the full set of master styles that we
introduced earlier (see
[QuickStart, "Add some style"](../quickstart.html#add-some-style)).
These correspond to the full set of master styles that we installed earlier during [setup](../guide/setup.html).
Here is an excerpt:
+makeExcerpt('styles.css (excerpt)', 'toh')

View File

@ -618,3 +618,10 @@ block file-summary
hero-search.component.css,
rxjs-extensions.ts`
)
.l-sub-section
:marked
### Next Step
Return to the [learning path](../guide/learning-angular.html#architecture) where
you can read about the concepts and practices you discovered in this tutorial.

View File

@ -19,8 +19,7 @@
"icon": "query-builder",
"title": "快速起步",
"subtitle": "TypeScript",
"description": "Angular快速起步",
"banner": "本“快速起步”指南将演示如何用TypeScript构建并运行简单的Angular应用。"
"banner": "快速体验 Angular"
},
"tutorial": {

View File

@ -1,33 +1,34 @@
include _util-fns
:marked
Good tools make application development quicker and easier to maintain than
if we did everything by hand.
The [**Angular-CLI**](https://cli.angular.io/) is a **_command line interface_** tool
that can create a project, add files, and perform a variety of on-going development tasks such
as testing, bundling, and deployment.
Our goal in this CLI QuickStart chapter is to build and run a super-simple Angular
application in TypeScript, using Angular-CLI
while adhering to the [Style Guide](./guide/style-guide.html) recommendations that
benefit _every_ Angular project.
By the end of the chapter, we'll have a basic understanding of development with the CLI
and a foundation for both these documentation samples and our real world applications.
We'll pursue these ends in the following high-level steps:
1. [Set up](#devenv) the development environment
2. [Create](#create-proj) a new project and skeleton application
3. [Serve](#serve) the application
4. [Edit](#first-component) the application
.l-main-section
h2#devenv Step 1. Set up the Development Environment
:marked
We need to set up our development environment before we can do anything.
Install **[Node.js® and npm](https://nodejs.org/en/download/)**
if they are not already on your machine.
.l-sub-section
@ -37,15 +38,15 @@ h2#devenv Step 1. Set up the Development Environment
Older versions produce errors.
:marked
Then **install the [Angular-CLI](https://github.com/angular/angular-cli)** globally.
code-example(format="").
npm install -g angular-cli
.l-main-section
h2#create-project Step 2. Create a new project
:marked
Open a terminal window.
.alert.is-important
:marked
_Windows Developers_: open a console window _as an **administrator**_.
@ -75,9 +76,9 @@ code-example(format="").
:marked
The `ng serve` command launches the server, watches our files,
and rebuilds the app as we make changes to the files.
Open a browser on `http://localhost:4200/`; the app greets us with a message:
figure.image-display
img(src='/resources/images/devguide/cli-quickstart/app-works.png' alt="Our app works!")
@ -96,19 +97,19 @@ h2#first-component Step 4: Edit our first Angular component
:marked
Open the component file and change the `title` property from _cli-quickstart works!_ to _My First Angular App_:
+makeExample('cli-quickstart/ts/src/app/cli-quickstart.component.ts', 'title', 'src/app/cli-quickstart.component.ts')(format=".")
:marked
The browser reloads automatically and we see the revised title. That's nice, but we can make it look better.
Open `src/app/cli-quickstart.component.css` and give our component some style
+makeExample('cli-quickstart/ts/src/app/cli-quickstart.component.css', null, 'src/app/cli-quickstart.component.css')(format=".")
figure.image-display
img(src='/resources/images/devguide/cli-quickstart/hello-angular.png' alt="Output of QuickStart app")
:marked
Looking good!
@ -177,7 +178,7 @@ h3#component-decorator @Component decorator
:marked
This particular metadata object has four fields, a `moduleId`, a `selector` a `templateUrl` and an array of `styleUrls`.
The **moduleId** specifies the location of _this_ component definition file
so that Angular can find the corresponding _template_ and _style_ files with URLs that
are relative to this component file.
@ -193,14 +194,14 @@ h3#component-decorator @Component decorator
The **templateUrl** locates the component's companion template HTML file.
The template tells Angular how to render this component's view.
Our template is a single `<h1>` element surrounding some peculiar Angular data binding syntax.
+makeExample('src/app/cli-quickstart.component.html', null, 'src/app/cli-quickstart.component.html')(format='.')
:marked
The `{{title}}` is an _interpolation_ binding that causes Angular to display the component's
`title` property. After out edit, Angular displays "Hello Angular!".
`title` property. After out edit, Angular displays "Hello Angular".
We'll learn more about data binding as we read through the documentation.
The **styleUrls** array specifies the location(s) of the component's private CSS style file(s).
The CLI generated an empty file for us and we added styles to it.
@ -216,10 +217,10 @@ h3#component-decorator @Component decorator
:marked
### The *main.ts* file
How does Angular know what to do with our component? We have to tell it.
We _bootstrap_ our application in the file `main.ts`.
+makeExcerpt('src/main.ts', 'important')
:marked
@ -257,17 +258,17 @@ h3#component-decorator @Component decorator
We might launch the `CliQuickstartAppComponent` in multiple environments with different bootstrappers.
Testing the component is much easier if it doesn't also try to run the entire application.
Let's make the small extra effort to do it *the right way*.
### Loading the application with SystemJS
The CLI uses `System.js` to load the application. We just need to call `System.import` and pass it our `main.ts`
file to boot our application.
+makeExcerpt('src/index.html', 'import')
:marked
### Displaying the root component
When Angular calls the `bootstrap` function in `main.ts`, it reads the `CliQuickstartAppComponent`
metadata, finds the `cli-quickstart-app` selector, locates an element tag named `cli-quickstart-app`
in the `<body>` tag of the `index.html`, and renders our application's view between those tags.

View File

@ -2,7 +2,7 @@
"index": {
"title": "烹饪宝典",
"navTitle": "概览",
"description": "一组常见Angular应用场景的“烹饪宝典”"
"intro": "一组常见Angular应用场景的“烹饪宝典”"
},
"aot-compiler": {
@ -57,8 +57,8 @@
},
"ts-to-js": {
"title": "从TypeScript到JavaScript",
"intro": "把Angular的TypeScript范例转换为ES6和ES5 JavaScript"
"title": "从 TypeScript JavaScript",
"intro": "把 Angular TypeScript 范例转换为 ES6 ES5 JavaScript"
},
"visual-studio-2015": {

View File

@ -233,9 +233,9 @@ table(width="100%")
Angular 2没有引导指令。
我们总是通过显式调用一个`bootstrap`函数,并传入应用模块的名字(`AppComponent`)来启动应用。
For more information see [Quick Start](../quickstart.html).
For more information see the [Setup](../guide/setup.html) page.
要了解更多,参见[“快速起步”](../quickstart.html)。
要了解更多,参见[搭建](../guide/setup.html)。
tr(style=top)
td
:marked

View File

@ -56,7 +56,7 @@ a#overview
这是本文档中展示过的标准开发方式。
它很不错,但是有自己的缺点。
JiT compilation incurs a runtime performance penalty.
JiT compilation incurs a runtime performance penalty.
Views take longer to render because of the in-browser compilation step.
The application is bigger because it includes the Angular compiler
and a lot of library code that the application won't actually need.
@ -98,7 +98,7 @@ a#aot-jit
**渲染得更快**
With AoT, the browser downloads a pre-compiled version of the application.
With AoT, the browser downloads a pre-compiled version of the application.
The browser loads executable code so it can render the application immediately, without waiting to compile the app first.
使用AoT浏览器下载预编译版本的应用程序。
@ -118,7 +118,7 @@ a#aot-jit
**需要下载的Angular框架体积更小**
There's no need to download the Angular compiler if the app is already compiled.
There's no need to download the Angular compiler if the app is already compiled.
The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.
如果应用已经编译过了自然不需要再下载Angular编译器了。
@ -155,10 +155,10 @@ a#compile
### 为离线编译做准备
Take the <a href='/docs/ts/latest/quickstart.html'>QuickStart</a> as a starting point.
Take the <a href='../guide/setup.html'>Setup</a> as a starting point.
A few minor changes to the lone `app.component` lead to these two class and html files:
本烹饪书以<a href='/docs/ts/latest/quickstart.html'>“快速起步”</a>作为起始点。
本烹饪书以<a href='../guide/setup.html'>搭建</a>作为起始点。
只要单独对`app.component`文件的类文件和html文件做少量修改就可以了。
+makeTabs(
@ -182,7 +182,7 @@ code-example(format='.').
你要用`@angular/compiler-cli`包中提供的`ngc`编译器来代替TypeScript编译器`tsc`)。
`ngc` is a drop-in replacement for `tsc` and is configured much the same way.
`ngc` is a drop-in replacement for `tsc` and is configured much the same way.
`ngc`是一个`tsc`的高仿替代品,它们的配置方式几乎完全一样。
@ -202,14 +202,14 @@ code-example(format='.').
`compilerOptions`部分只修改了一个属性:**把`module`设置为`es2015`。
这一点非常重要,我们会在后面的[摇树优化](#tree-shaking)部分解释为什么。
What's really new is the `ngc` section at the bottom called `angularCompilerOptions`.
What's really new is the `ngc` section at the bottom called `angularCompilerOptions`.
Its `"genDir"` property tells the compiler
to store the compiled output files in a new `aot` folder.
`ngc`区真正新增的内容是底部的`angularCompilerOptions`。
它的`"genDir"`属性告诉编译器把编译结果保存在新的`aot`目录下。
The `"skipMetadataEmit" : true` property prevents the compiler from generating metadata files with the compiled application.
The `"skipMetadataEmit" : true` property prevents the compiler from generating metadata files with the compiled application.
Metadata files are not necessary when targeting TypeScript files, so there is no reason to include them.
`"skipMetadataEmit" : true`属性阻止编译器为编译后的应用生成元数据文件。
@ -237,11 +237,11 @@ code-example(format='.').
`ngc`希望`-p`选项指向一个`tsconfig.json`文件,或者一个包含`tsconfig.json`文件的目录。
After `ngc` completes, look for a collection of _NgFactory_ files in the `aot` folder (the folder specified as `genDir` in `tsconfig-aot.json`).
After `ngc` completes, look for a collection of _NgFactory_ files in the `aot` folder (the folder specified as `genDir` in `tsconfig-aot.json`).
在`ngc`完成时,会在`aot`目录下看到一组*NgFactory*文件(该目录是在`tsconfig-aot.json`的`genDir`属性中指定的)。
These factory files are essential to the compiled application.
These factory files are essential to the compiled application.
Each component factory creates an instance of the component at runtime by combining the original class file
and a JavaScript representation of the component's template.
Note that the original component class is still referenced internally by the generated factory.
@ -284,7 +284,7 @@ a#bootstrap
引导的方式从引导`AppModule`改成了引导生成的模块工厂:`AppModuleNgFactory`。
Switch from the `platformBrowserDynamic.bootstrap` used in JiT compilation to
Switch from the `platformBrowserDynamic.bootstrap` used in JiT compilation to
`platformBrowser().bootstrapModuleFactory` and pass in the `AppModuleNgFactory`.
从使用JiT编译时的`platformBrowserDynamic.bootstrap`换成了`platformBrowser().bootstrapModuleFactory`,并把`AppModuleNgFactory`传进去。
@ -318,7 +318,7 @@ a#tree-shaking
AoT编译为接下来通过一个叫做*摇树优化*的过程做好了准备。
摇树优化器从上到下遍历依赖图谱,并且*摇掉*用不到的代码,这些代码就像是圣诞树中那些死掉的松针一样。
Tree Shaking can greatly reduce the downloaded size of the application
Tree Shaking can greatly reduce the downloaded size of the application
by removing unused portions of both source and library code.
In fact, most of the reduction in small apps comes from removing unreferenced Angular features.
@ -330,7 +330,7 @@ a#tree-shaking
例如,这个演示程序中没有用到`@angular/forms`库中的任何东西那么也就没有理由去下载这些与表单有关的Angular代码了。摇树优化可以帮你确保这一点。
Tree Shaking and AoT compilation are separate steps.
Tree Shaking and AoT compilation are separate steps.
Tree Shaking can only target JavaScript code.
AoT compilation converts more of the application to JavaScript,
which in turn makes more of the application "Tree Shakable".
@ -414,14 +414,14 @@ code-example(format='.').
可观察对象库*RxJS*是Angular所依赖的基础之一它就是发布成了ES5 JavaScript的*CommonJS*模块。
Luckily there is a Rollup plugin that modifies _RxJs_
Luckily there is a Rollup plugin that modifies _RxJs_
to use the ES `import` and `export` statements that Rollup requires.
Rollup then preserves in the final bundle the parts of `RxJS` referenced by the application.
幸运的是有一个Rollup插件它会修改*RxJS*以使用Rollup所需的ES`import`和`export`语句。
然后Rollup就可以把该应用中用到的那部分`RxJS`代码留在“捆”文件中了。
+makeExample('cb-aot-compiler/ts/rollup-config.js','commonjs','rollup-config.js (CommonJs to ES2015 Plugin)')(format='.')
+makeExample('cb-aot-compiler/ts/rollup-config.js','commonjs','rollup-config.js (CommonJs to ES2015 Plugin)')(format='.')
:marked
*Minification*
@ -475,7 +475,7 @@ a#load
## 加载捆文件
Loading the generated application bundle does not require a module loader like SystemJS.
Loading the generated application bundle does not require a module loader like SystemJS.
Remove the scripts that concern SystemJS.
Instead, load the bundle file using a single `script` tag:
@ -483,7 +483,7 @@ a#load
移除与SystemJS有关的那些脚本吧。
改用`script`标签来加载这些捆文件:
+makeExample('cb-aot-compiler/ts/index.html','bundle','index.html (load bundle)')(format='.')
+makeExample('cb-aot-compiler/ts/index.html','bundle','index.html (load bundle)')(format='.')
a#serve
.l-main-section
@ -538,7 +538,7 @@ a#toh
## 英雄指南
The sample above is a trivial variation of the QuickStart app.
The sample above is a trivial variation of the QuickStart app.
In this section you apply what you've learned about AoT compilation and Tree Shaking
to an app with more substance, the tutorial [_Tour of Heroes_](../tutorial/toh-pt6.html).
@ -591,19 +591,13 @@ a#toh
The AoT version loads the entire application in a single script, `aot/dist/build.js`.
It does not need `SystemJS` or the `reflect-metadata` shim; those scripts are absent from its `index.html`
AoT版本用一个单独的脚本来加载整个应用 - `aot/dist/build.js`。它不需要`SystemJS`和`reflect-metadata`垫片,所以它们不会出现在`index.html`中。
***main.ts***
***main.ts***
JiT and AoT applications boot in much the same way but require different Angular libraries to do so.
The key differences, covered in the [Bootstrap](#bootstrap) section above,
are evident in these `main` files which can and should reside in the same folder:
JiT和AoT应用启动非常相似但需要加载不同的Angular库来实现。
主要的差异,见上面的[启动](#bootstrap)一节,
可以在那些`main`文件中明显看出区别,它们可以也应该位于同一目录。
AoT版本用一个单独的脚本来加载整个应用 - `aot/dist/build.js`。它不需要`SystemJS`和`reflect-metadata`垫片,所以它们不会出现在`index.html`中。
+makeTabs(
`toh-6/ts/app/main-aot.ts,
@ -616,14 +610,12 @@ a#toh
:marked
***Component-relative Template URLS***
***相对组件的模板路径***
The AoT compiler requires that `@Component` URLS for external templates and css files be _component-relative_.
That means that the value of `@Component.templateUrl` is a URL value _relative_ to the component class file.
For example, a `'hero.component.html'` URL means that the template file is a sibling of its companion `hero.component.ts` file.
AoT编译器要求`@Component`外部模板和CSS文件的路径是相对组件的。
意思是,`@Component.templateUrl`的值是一个相对组件类文件`foo.component.html`的路径,不管`foo.component.ts`在项目的哪个目录
意思是,`@Component.templateUrl`的值是*相对*组件类文件的路径,比如`'hero.component.html'`路径的意思是模板文件在`hero.component.ts`文件的隔壁
While JiT app URLs are more flexible, stick with _component-relative_ URLs for compatibility with AoT compilation.
@ -769,7 +761,7 @@ code-example(format='.').
### 检查包裹
It's fascinating to see what the generated JavaScript bundle looks like after Rollup.
It's fascinating to see what the generated JavaScript bundle looks like after Rollup.
The code is minified, so you won't learn much from inspecting the bundle directly.
But the <a href="https://github.com/danvk/source-map-explorer/blob/master/README.md" target="_blank">source-map-explorer</a>
tool can be quite revealing.

View File

@ -2,80 +2,80 @@ include ../_util-fns
:marked
We can't always justify the cost and time to build handcrafted forms, especially if we'll need a great number of them, they're similar to each other, and they change frequently to meet rapidly changing business and regulatory requirements.
有时候手动编写和维护表单所需工作量和时间会过大。特别是在需要编写大量表单时。表单都很相似,而且随着业务和监管需求的迅速变化,表单也要随之变化,这样维护的成本过高。
It may be more economical to create the forms dynamically, based on metadata that describe the business object model.
基于业务对象模型的元数据,动态创建表单可能会更划算。
In this cookbook we show how to use `formGroup` to dynamically render a simple form with different control types and validation.
It's a primitive start.
It might evolve to support a much richer variety of questions, more graceful rendering, and superior user experience.
All such greatness has humble beginnings.
在此烹饪宝典中,我们会展示如何利用`formGroup`来动态渲染一个简单的表单,包括各种控件类型和验证规则。
这个起点很简陋,但可以在这个基础上添加丰富多彩的问卷问题、更优美的渲染以及更卓越的用户体验。
In our example we use a dynamic form to build an online application experience for heroes seeking employment.
The agency is constantly tinkering with the application process.
We can create the forms on the fly *without changing our application code*.
在本例中,我们使用动态表单,为正在找工作的英雄们创建一个在线申请表。英雄管理局会不断修改申请流程,我们要在*不修改应用代码*的情况下,动态创建这些表单。
<a id="toc"></a>
:marked
## Table of contents
## 目录
## 目录
[Bootstrap](#bootstrap)
[程序启动](#bootstrap)
[Question Model](#object-model)
[问卷问题模型](#object-model)
[Form Component](#form-component)
[表单组件](#form-component)
[Questionnaire Metadata](#questionnaire-metadata)
[问卷元数据](#questionnaire-metadata)
[Dynamic Template](#dynamic-template)
[动态模板](#dynamic-template)
:marked
**See the <live-example name="cb-dynamic-form"></live-example>**.
**参见<live-example name="cb-dynamic-form">在线例子</live-example>**。
.l-main-section
<a id="bootstrap"></a>
:marked
## Bootstrap
## 程序启动
We start by creating an `NgModule` called `AppModule`.
让我们从创建一个名叫`AppModule`的`NgModule`开始。
In our example we will be using Reactive Forms.
在本例子中我们将使用响应式表单Reactive Forms
Reactive Forms belongs to a different `NgModule` called `ReactiveFormsModule`, so in order to access any Reactive Forms directives, we have to import `ReactiveFormsModule` from `AppModule`.
响应式表单属于另外一个叫做`ReactiveFormsModule`的`NgModule`,所以,为了使用响应式表单类的指令,我们得往`AppModule`中引入`ReactiveFormsModule`模块。
Reactive Forms belongs to a different `NgModule` called `ReactiveFormsModule`, so in order to access any Reactive Forms directives, we have to import `ReactiveFormsModule` from the `@angular/forms` library.
响应式表单属于另外一个叫做`ReactiveFormsModule`的`NgModule`,所以,为了使用响应式表单类的指令,我们得往`@angular/forms`库中引入`ReactiveFormsModule`模块。
We bootstrap our `AppModule` in main.ts.
我们在main.ts中启动`AppModule`。
+makeTabs(
@ -90,17 +90,17 @@ include ../_util-fns
<a id="object-model"></a>
:marked
## Question Model
## 问卷问题模型
The next step is to define an object model that can describe all scenarios needed by the form functionality.
The hero application process involves a form with a lot of questions.
The "question" is the most fundamental object in the model.
第一步是定义一个对象模型,用来描述所有表单功能需要的场景。英雄的申请流程涉及到一个包含很多问卷问题的表单。问卷问题是最基础的对象模型。
We have created `QuestionBase` as the most fundamental question class.
下面是我们建立的最基础的问卷问题基类,名叫`QuestionBase`。
+makeExample('cb-dynamic-form/ts/app/question-base.ts','','app/question-base.ts')
@ -110,9 +110,9 @@ include ../_util-fns
The idea is that the form will be bound to specific question types and render the appropriate controls dynamically.
在这个基础上,我们派生出两个新类`TextboxQuestion` 和 `DropdownQuestion`,分别代表文本框和下拉框。这么做的初衷是,表单能动态绑定到特定的问卷问题类型,并动态渲染出合适的控件。
`TextboxQuestion` supports multiple html5 types like text, email, url etc via the `type` property.
`TextboxQuestion`可以通过`type`属性来支持多种HTML5元素类型比如文本、邮件、网址等。
+makeExample('cb-dynamic-form/ts/app/question-textbox.ts',null,'app/question-textbox.ts')(format='.')
@ -121,34 +121,34 @@ include ../_util-fns
`DropdownQuestion` presents a list of choices in a select box.
`DropdownQuestion`表示一个带可选项列表的选择框。
+makeExample('cb-dynamic-form/ts/app/question-dropdown.ts',null,'app/question-dropdown.ts')(format='.')
:marked
Next we have defined `QuestionControlService`, a simple service for transforming our questions to a `FormGroup`.
In a nutshell, the form group consumes the metadata from the question model and allows us to specify default values and validation rules.
接下来,我们定义了`QuestionControlService`,一个可以把问卷问题转换为`FormGroup`的服务。
简而言之,这个`FormGroup`使用问卷模型的元数据,并允许我们设置默认值和验证规则。
+makeExample('cb-dynamic-form/ts/app/question-control.service.ts',null,'app/question-control.service.ts')(format='.')
<a id="form-component"></a>
:marked
## Question form components
## 问卷表单组件
Now that we have defined the complete model we are ready to create components to represent the dynamic form.
现在我们已经有一个定义好的完整模型了,接着就可以开始创建一个展现动态表单的组件。
:marked
`DynamicFormComponent` is the entry point and the main container for the form.
`DynamicFormComponent`是表单的主要容器和入口点。
`DynamicFormComponent`是表单的主要容器和入口点。
+makeTabs(
`cb-dynamic-form/ts/app/dynamic-form.component.html,
cb-dynamic-form/ts/app/dynamic-form.component.ts`,
@ -160,10 +160,10 @@ include ../_util-fns
It presents a list of questions, each question bound to a `<df-question>` component element.
The `<df-question>` tag matches the `DynamicFormQuestionComponent`,
the component responsible for rendering the details of each _individual_ question based on values in the data-bound question object.
它代表了问卷问题列表,每个问题都被绑定到一个`<df-question>`组件元素。
`<df-question>`标签匹配到的是组件`DynamicFormQuestionComponent`,该组件的职责是根据各个问卷问题对象的值来动态渲染表单控件。
+makeTabs(
`cb-dynamic-form/ts/app/dynamic-form-question.component.html,
cb-dynamic-form/ts/app/dynamic-form-question.component.ts`,
@ -177,63 +177,63 @@ include ../_util-fns
The `ngSwitch` determines which type of question to display.
请注意,这个组件能代表模型里的任何问题类型。目前,还只有两种问题类型,但可以添加更多类型。可以用`ngSwitch`决定显示哪种类型的问题。
In both components we're relying on Angular's **formGroup** to connect the template HTML to the
underlying control objects, populated from the question model with display and validation rules.
在这两个组件中我们依赖Angular的**formGroup**来把模板HTML和底层控件对象连接起来该对象从问卷问题模型里获取渲染和验证规则。
`formControlName` and `formGroup` are directives defined in `ReactiveFormsModule`. Our templates can can access these directives directly since we imported `ReactiveFormsModule` from `AppModule`.
`formControlName`和`formGroup`是在`ReactiveFormsModule`中定义的指令。我们之所以能在模板中使用它们,是因为我们往`AppModule`中导入了`ReactiveFormsModule`。
<a id="questionnaire-metadata"></a>
:marked
## Questionnaire data
## 问卷数据
:marked
`DynamicFormComponent` expects the list of questions in the form of an array bound to `@Input() questions`.
`DynamicForm`期望得到一个问题列表,该列表被绑定到`@Input() questions`属性。
The set of questions we have defined for the job application is returned from the `QuestionService`.
The set of questions we have defined for the job application is returned from the `QuestionService`.
In a real app we'd retrieve these questions from storage.
`QuestionService`会返回为工作申请表定义的那组问题列表。在真实的应用程序环境中,我们会从数据库里获得这些问题列表。
The key point is that we control the hero job application questions entirely through the objects returned from `QuestionService`.
The key point is that we control the hero job application questions entirely through the objects returned from `QuestionService`.
Questionnaire maintenance is a simple matter of adding, updating, and removing objects from the `questions` array.
关键是,我们完全根据`QuestionService`返回的对象来控制英雄的工作申请表。
要维护这份问卷,只要非常简单的添加、更新和删除`questions`数组中的对象就可以了。
+makeExample('cb-dynamic-form/ts/app/question.service.ts','','app/question.service.ts')
+makeExample('cb-dynamic-form/ts/app/question.service.ts','','app/question.service.ts')
:marked
Finally, we display an instance of the form in the `AppComponent` shell.
最后,在`AppComponent`里显示出表单。
+makeExample('cb-dynamic-form/ts/app/app.component.ts','','app.component.ts')
<a id="dynamic-template"></a>
:marked
## Dynamic Template
## 动态模板
Although in this example we're modelling a job application for heroes, there are no references to any specific hero question
Although in this example we're modelling a job application for heroes, there are no references to any specific hero question
outside the objects returned by `QuestionService`.
在这个例子中,虽然我们是在为英雄的工作申请表建模,但是除了`QuestionService`返回的那些对象外,没有其它任何地方是与英雄有关的。
This is very important since it allows us to repurpose the components for any type of survey
as long as it's compatible with our *question* object model.
The key is the dynamic data binding of metadata used to render the form
without making any hardcoded assumptions about specific questions.
In addition to control metadata, we are also adding validation dynamically.
这点非常重要,因为只要与*问卷*对象模型兼容,就可以在任何类型的调查问卷中复用这些组件。
这里的关键是用到元数据的动态数据绑定来渲染表单,对问卷问题没有任何硬性的假设。除控件的元数据外,还可以动态添加验证规则。
@ -241,21 +241,21 @@ include ../_util-fns
When the form is valid, we can click *Save* and the app renders the current form values as JSON.
This proves that any user input is bound back to the data model.
Saving and retrieving the data is an exercise for another time.
表单验证通过之前,*保存*按钮是禁用的。验证通过后,就可以点击*保存*按钮程序会把当前值渲染成JSON显示出来。
这表明任何用户输入都被传到了数据模型里。至于如何储存和提取数据则是另一话题了。
:marked
The final form looks like this:
完整的表单看起来是这样的:
figure.image-display
img(src="/resources/images/cookbooks/dynamic-form/dynamic-form.png" alt="Dynamic-Form")
:marked
[Back to top](#top)
[回到顶部](#top)

View File

@ -28,20 +28,22 @@ block includes
.l-main-section#A
+ifDocsFor('ts')
a#aot
a#aot
:marked
## Ahead-of-Time (AoT) compilation
## 预ahead-of-time, AoT编译
.l-sub-section
:marked
## Ahead-of-time (AoT) compilation
## 预ahead-of-time, AoT编译
.l-sub-section
:marked
You can compile Angular applications at build-time.
By compiling your application using the compiler-cli, `ngc`, you can bootstrap directly
to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle.
Ahead-of-time compiled applications also benefit from decreased load time and increased performance.
You can compile Angular applications at build-time.
By compiling your application<span if-docs="ts"> using the compiler-cli, `ngc`</span>, you can bootstrap directly
to a<span if-docs="ts"> module</span> factory, meaning you don't need to include the Angular compiler in your JavaScript bundle.
Ahead-of-time compiled applications also benefit from decreased load time and increased performance.
开发者可以在构造时(build-time)编译Angular应用程序。通过`Compiler-cli` - `ngc`编译应用程序,应用可以从一个模块工厂(Module Factory)直接启动意思是不再需要把Angular编译器添加到JavaScript包中。预编译的应用程序将加载迅速并具有更高的性能。
开发者可以在构造时(build-time)编译Angular应用程序。通过`Compiler-cli` - `ngc`编译应用程序,应用可以从一个模块工厂(Module Factory)直接启动意思是不再需要把Angular编译器添加到JavaScript包中。预编译的应用程序将加载迅速并具有更高的性能。
+ifDocsFor('ts')
:marked
## Angular module
@ -145,12 +147,6 @@ block includes
Angular的每个[范围化包(Scoped Package)](#scoped-package)都有一个叫做`index`的封装桶。
That's why we can write this:
这就是为什么可以这样写:
+makeExcerpt('quickstart/ts/app/app.component.ts', 'import', '')
.alert.is-important
:marked
Note that you can often achieve this using [Angular modules](#angular-module) instead.
@ -180,9 +176,11 @@ block includes
.l-sub-section
block bootstrap-defn-top
:marked
You launch an Angular application by "bootstrapping" it using the application root Angular module (`AppModule`). Bootstrapping identifies an application's top level "root" [component](#component), which is the first component that is loaded for the application. For more information, see [QuickStart](!{docsLatest}/quickstart.html).
You launch an Angular application by "bootstrapping" it using the application root Angular module (`AppModule`). Bootstrapping identifies an application's top level "root" [component](#component), which is the first component that is loaded for the application.
For more information, see the [Setup](!{docsLatest}/guide/setup.html) page.
通过一个名叫`bootstrap`的方法来引导Angular应用程序。这个`bootstrap`方法会识别应用程序的顶级“根”[组件(Component)](#component),并可能通过[依赖注入体系(Dependency Injection System)](#dependency-injection)注册服务的[提供商(Provider)](#provider)。要了解详情,参见[快速起步](!{docsLatest}/quickstart.html)。
通过一个名叫`bootstrap`的方法来引导Angular应用程序。这个`bootstrap`方法会识别应用程序的顶级“根”[组件(Component)](#component),也就是应用加载的第一个组件。
要了解详情,参见[搭建](!{docsLatest}/setup.html)页。
:marked
You can bootstrap multiple apps in the same `index.html`, each with its own top level root.
@ -588,14 +586,15 @@ a#H
.l-main-section#J
+ifDocsFor('ts')
a#jit
:marked
## Just-in-time (JiT) compilation
## 即时just-in-time, JiT编译
.l-sub-section
a#jit
:marked
## Just-in-Time (JiT) compilation
## 即时just-in-time, JiT编译
.l-sub-section
:marked
With Angular _just-in-time_ bootstrapping you compile your components and modules in the browser
With Angular _just-in-time_ bootstrapping you compile your components<span if-docs="ts"> and modules</span> in the browser
and launch the application dynamically. This is a good choice during development.
Consider using the [ahead-of-time](#aot) mode for production apps.
@ -908,15 +907,12 @@ a#Q
## Routing component
## 路由组件Routing Component
.l-sub-section
block routing-component-defn
:marked
An Angular [component](#component) with a RouterOutlet that displays views based on router navigations.
:marked
An Angular [component](#component) with a `RouterOutlet` that displays views based on router navigations.
带有RouterOutlet的Angular[组件](#component)基于路由器导航来显示视图。
带有RouterOutlet的Angular[组件](#component)基于路由器导航来显示视图。For more information, see the [Routing & Navigation](!{docsLatest}/guide/router.html) page.
For more information, see the [Routing & Navigation](!{docsLatest}/guide/router.html) page.
要了解更多,请参见[路由与导航](!{docsLatest}/guide/router.html)页。
要了解更多,请参见[路由与导航](!{docsLatest}/guide/router.html)页。
.l-main-section#S
@ -1082,7 +1078,7 @@ a#snake-case
## TypeScript
.l-sub-section
:marked
A version of JavaScript that supports most [ECMAScript 2015](#ecmascript=2015)
A version of JavaScript that supports most [ECMAScript 2015](#es2015)
language features such as [decorators](#decorator).
一种支持了几乎所有[ECMAScript 2015](#ecmascript=2015)语言特性和一些未来版本可能有的特性(比如[装饰器(Decorator)](#decorator))的JavaScript语言。

View File

@ -2,11 +2,29 @@
"index": {
"title": "文档概览",
"navTitle": "概览",
"description": "如何阅读本文档",
"intro": "如何阅读本文档",
"nextable": true,
"basics": true
},
"setup": {
"title": "Setup for local development",
"navTitle": "Setup",
"intro": "Install the Angular QuickStart seed for faster, more efficient development on your machine",
"nextable": true,
"hideNextPage": true,
"basics": true
},
"learning-angular": {
"title": "Learning Angular",
"navTitle": "Learning Angular",
"intro": "A suggested path through the documentation for Angular newcomers",
"nextable": true,
"hideNextPage": true,
"basics": true
},
"architecture": {
"title": "架构概览",
"navTitle": "架构",
@ -15,6 +33,15 @@
"basics": true
},
"appmodule": {
"title": "AppModule: the root module",
"navTitle": "The Root Module",
"intro": "Tell Angular how to construct and bootstrap the app in the root \"AppModule\".",
"nextable": true,
"basics": true
},
"displaying-data": {
"title": "显示数据",
"intro": "属性绑定机制把数据显示到UI上。",
@ -136,6 +163,11 @@
"intro": "开发“内容安全”的Angular应用。"
},
"setup-systemjs-anatomy": {
"title": "Setup Anatomy",
"intro": "Inside the local development environment for SystemJS"
},
"structural-directives": {
"title": "结构型指令",
"intro": "Angular有一个强力的模板引擎它能让你轻松维护元素的DOM树结构。"

View File

@ -0,0 +1,138 @@
include ../_util-fns
:marked
An Angular module class describes how the application parts fit together.
Every application has at least one Angular module, the _root_ module
that you [bootstrap](#main) to launch the application.
You can call it anything you want. The conventional name is `AppModule`.
The [setup](setup.html) instructions produce a new project with the following minimal `AppModule`.
You'll evolve this module as your application grows.
+makeExample('setup/ts/app/app.module.ts','', 'app/app.module.ts')(format='.')
:marked
After the `import` statements, you come to a class adorned with the
**`@NgModule`** [_decorator_](glossary.html#decorator '"Decorator" explained').
The `@NgModule` decorator identifies `AppModule` as an Angular module class (also called an `NgModule` class).
`@NgModule` takes a _metadata_ object that tells Angular how to compile and launch the application.
* **_imports_** &mdash; the `BrowserModule` that this and every application needs to run in a browser.
* **_declarations_** &mdash; the application's lone component, which is also ...
* **_bootstrap_** &mdash; the _root_ component that Angular creates and inserts into the `index.html` host web page.
The [Angular Modules (NgModules)](ngmodule.html) guide dives deeply into the details of Angular modules.
All you need to know at the moment is a few basics about these three properties.
a#imports
:marked
### The _imports_ array
Angular modules are a way to consolidate features that belong together into discrete units.
Many features of Angular itself are organized as Angular modules.
HTTP services are in the `HttpModule`. The router is in the `RouterModule`.
Eventually you may create a feature module.
Add a module to the `imports` array when the application requires its features.
_This_ application, like most applications, executes in a browser.
Every application that executes in a browser needs the `BrowserModule` from `@angular/platform-browser`.
So every such application includes the `BrowserModule` in its _root_ `AppModule`'s `imports` array.
Other guide and cookbook pages will tell you when you need to add additional modules to this array.
.alert.is-important
:marked
**Only `NgModule` classes** go in the `imports` array. Don't put any other kind of class in `imports`.
.l-sub-section
:marked
Don't confuse the `import` statements at the top of the file with the Angular module's `imports` array.
They have different jobs.
The _JavaScript_ `import` statements give you access to symbols _exported_ by other files
so you can reference them within _this_ file.
They have nothing to do with Angular and Angular knows nothing about them.
The _module's_ `imports` array tells Angular about specific Angular modules &mdash; classes decorated with `@NgModule` &mdash;
that the application needs to function properly.
a#declarations
:marked
### The _declarations_ array
You must declare _every_ component in one (and _only one_) `NgModule` class.
You tell Angular which components belong to the `AppModule` by listing it in the module's `declarations` array.
As you create more components, you'll add them to `declarations`.
You'll learn to create two other kinds of classes &mdash;
[directives](attribute-directives.html) and [pipes](pipes.html) &mdash;
that you must also add to the `declarations` array.
.alert.is-important
:marked
**Only _declarables_** &mdash; _components_, _directives_ and _pipes_ &mdash; belong in the `declarations` array. &nbsp;
Don't put any other kind of class in `declarations`; _not_ `NgModule` classes, _not_ service classes, _not_ model classes.
a#bootstrap-array
:marked
### The _bootstrap_ array
You launch the application by [_bootstrapping_](#main) the root `AppModule`.
Among other things, the _bootstrapping_ process creates the component(s) listed in the `bootstrap` array
and inserts each one into the browser DOM.
Each bootstrapped component is the base of its own tree of components.
Inserting a bootstrapped component usually triggers a cascade of component creations that fill out that tree.
While you can put more than one component tree on a host web page, that's not typical.
Most applications have only one component tree and they bootstrap a single _root_ component.
You can call the one _root_ component anything you want but most developers call it `AppComponent`.
Which brings us to the _bootstrapping_ process itself.
a#main
l-main-section
:marked
## Bootstrap in _main.ts_
There are many ways to bootstrap an application.
The variations depend upon how you want to compile the application and where you want to run it.
In the beginning, you will compile the application dynamically with the _Just-in-Time (JiT)_ compiler
and you'll run it in a browser. You can learn about other options later.
The recommended place to bootstrap a JiT-compiled browser application is in a separate file
in the `app` folder named `app/main.ts`
+makeExample('setup/ts/app/main.ts','','app/main.ts')(format='.')
:marked
This code creates a browser platform for dynamic (JiT) compilation and
bootstrap's the `AppModule` described above.
The _bootstrapping_ process sets up the execution environment,
digs the _root_ `AppComponent` out of the module's `bootstrap` array, &nbsp;
creates an instance of the component and inserts it within the element tag identified by the component's `selector`.
The `AppComponent` selector &mdash; here and in most documentation samples &mdash; is `my-app`
so Angular looks for a `<my-app>` tag in the `index.html` like this one ...
+makeExample('setup/ts/index.html','my-app')(format='.')
:marked
... and displays the `AppComponent` there.
This file is very stable. Once you've set it up, you may never change it again.
a#quickstart-appmodule
l-main-section
:marked
## QuickStart's _AppModule_
Every Angular application must have a root `NgModule`, even the [QuickStart](../quickstart.html).
You didn't see it but it was there.
A script in the `index.html` generated a hidden `AppModule` and bootstrapped it for you
so you could focus on the `AppComponent` and discover the _essential Angular_ more quickly.
If you're feeling adventurous, add your own `AppModule` and `main.ts` to the
live code in the _QuickStart_ plunker.
Remove the following `<script>` tag from the `index.html` and see _your_ work in action.
+makeExample('quickstart/ts/index.html','autobootstrap','Remove this script tag from "index.html"')(format='.')

View File

@ -5,7 +5,7 @@ block includes
:marked
Angular is a framework for building client applications in HTML and
either JavaScript or a language (like Dart or TypeScript) that compiles to JavaScript.
either JavaScript or a language like TypeScript that compiles to JavaScript.
Angular是一个用HTML和JavaScript或者一个可以编译成JavaScript的语言例如Dart或者TypeScript来构建客户端应用的框架。
@ -98,7 +98,7 @@ figure
Angular应用是模块化的并且Angular有自己的模块系统它被称为_Angular模块_或_NgModules_。
_Angular modules_ are a big deal.
_Angular modules_ are a big deal.
This page introduces modules; the [Angular modules](ngmodule.html) page covers them in depth.
_Angular模块_很重要。
@ -106,11 +106,12 @@ figure
<br class="l-clear-both"><br>
:marked
Every Angular app has at least one module, the _root module_, conventionally named `AppModule`.
Every Angular app has at least one Angular module class, [the _root module_](appmodule.html "AppModule: the root module"),
conventionally named `AppModule`.
每个Angular应用至少有一个模块_根模块_习惯上命名为`AppModule`。
While the _root module_ may be the only module in a small application, most apps have many more
While the _root module_ may be the only module in a small application, most apps have many more
_feature modules_, each a cohesive block of code dedicated to an application domain,
a workflow, or a closely related set of capabilities.
@ -157,7 +158,7 @@ figure
* `providers` - [服务](#services)的创建者,并加入到全局服务表中,可用于应用任何部分。
* `bootstrap` - the main application view, called the _root component_,
* `bootstrap` - the main application view, called the _root component_,
that hosts all other app views. Only the _root module_ should set this `bootstrap` property.
* `bootstrap` - 指定应用的主视图称为_根组件_它是所有其它视图的宿主。只有_根模块_才能设置`bootstrap`属性。
@ -277,7 +278,7 @@ figure
要了解更多,参见[Angular模块](ngmodule.html)页。
.l-hr
.l-hr
.l-main-section
:marked
@ -333,7 +334,7 @@ figure
当用户在这个应用中漫游时Angular会创建、更新和销毁组件。
应用可以通过[生命周期钩子](lifecycle-hooks.html)在组件生命周期的各个时间点上插入自己的操作,例如上面声明的`ngOnInit()`。
.l-hr
.l-hr
.l-main-section
:marked
@ -488,7 +489,7 @@ figure
这种架构处理方式是你向代码中添加元数据以便Angular知道该怎么做。
.l-hr
.l-hr
.l-main-section
:marked
@ -668,7 +669,7 @@ block dart-bool
当然,我们也能编写自己的指令。像`HeroListComponent`这样的组件就是一种自定义指令。
.l-hr
.l-hr
.l-main-section
:marked
@ -769,7 +770,7 @@ figure
Angular帮助我们*追随*这些原则 —— 它让我们能轻易地把应用逻辑拆分到服务,并通过*依赖注入*来在组件中使用这些服务。
.l-hr
.l-hr
.l-main-section
:marked
@ -889,7 +890,7 @@ figure
* 把*提供商*注册到注入器。
.l-hr
.l-hr
.l-main-section
:marked

View File

@ -3,19 +3,19 @@ block includes
:marked
An **Attribute** directive changes the appearance or behavior of a DOM element.
**属性**型指令用于改变一个DOM元素的外观或行为。
:marked
# Contents
# 目录
* [Directives overview](#directive-overview)
* [指令概览](#directive-overview)
* [Build a simple attribute directive](#write-directive)
* [创建简单的属性型指令](#write-directive)
* [创建简单的属性型指令](#write-directive)
* [Apply the attribute directive to an element in a template](#apply-directive)
* [把这个属性型指令应用到模板中的元素](#apply-directive)
* [Respond to user-initiated events](#respond-to-user)
@ -24,7 +24,7 @@ block includes
* [使用数据绑定把值传到指令中](#bindings)
* [Bind to a second property](#second-property)
* [绑定第二个属性](#second-property)
试试<live-example>在线例子</live-example>。
@ -34,26 +34,27 @@ a#directive-overview
## Directives overview
## 指令概览
There are three kinds of directives in Angular:
在Angular中有三种类型的指令
1. Components&mdash;directives with a template.
1. 组件 - 拥有模板的指令
1. Structural directives&mdash;change the DOM layout by adding and removing DOM elements.
1. 结构型指令 - 通过添加和移除DOM元素改变DOM格局的指令
1. Attribute directives&mdash;change the appearance or behavior of an element.
1. 属性型指令 - 改变元素显示和行为的指令。
1. 属性型指令 - 改变元素显示和行为的指令。
*Components* are the most common of the three directives. Read more about creating them
in step three of [QuickStart](../quickstart.html#root-component).
*组件*是这三种指令中最常用的,我们在构建应用程序时会写大量组件。参见[快速开始](../quickstart.html#root-component)第三步,了解更多创建组件的信息。
*Components* are the most common of the three directives.
You saw a component for the first time in the [QuickStart](../quickstart.html) example.
*组件*是这三种指令中最常用的。
你在[快速开始](../quickstart.html#root-component)例子中第一次见到组件。
*Structural Directives* change the structure of the view. Two examples are [NgFor](template-syntax.html#ngFor) and [NgIf](template-syntax.html#ngIf)
in the [Template Syntax](template-syntax.html) page.
*结构型*指令会通过添加/删除DOM元素来更改DOM树布局。[NgFor](template-syntax.html#ngFor)和[NgIf](template-syntax.html#ngIf)就是两个最熟悉的例子。
*Attribute directives* are used as attributes of elements. The built-in [NgStyle](template-syntax.html#ngStyle) directive in the [Template Syntax](template-syntax.html) page, for example,
@ -65,33 +66,33 @@ a#directive-overview
a#write-directive
:marked
## Build a simple attribute directive
## 创建一个简单的属性型指令
An attribute directive minimally requires building a controller class annotated with
`@Directive`, which specifies the selector that identifies
the attribute.
The controller class implements the desired directive behavior.
属性型指令至少需要一个带有`@Directive`装饰器的控制器类。该装饰器指定了一个选择器,用于指出与此指令相关联的属性名字。
控制器类实现了指令需要具备的行为。
This page demonstrates building a simple attribute
directive to set an element's background color
when the user hovers over that element.
本章展示了如何创建简单的属性型指令,在用户鼠标悬浮在一个元素上时,改变它的背景色
.l-sub-section
:marked
Technically, a directive isn't necessary to simply set the background color. Style binding can set styles as follows:
实际上,指令并不一定只是简单的设置背景颜色。样式绑定可以像下面这样设置样式:
+makeExample('attribute-directives/ts/app/app.component.1.html','p-style-background')
:marked
Read more about [style binding](template-syntax.html#style-binding) on the [Template Syntax](template-syntax.html) page.
参见[模板语法](template-syntax.html)章的[样式绑定](template-syntax.html#style-binding)。
For a simple example, though, this will demonstrate how attribute directives work.
@ -100,44 +101,45 @@ a#write-directive
:marked
### Write the directive code
### 编写指令代码
Create a new project folder (`attribute-directives`) and follow the steps in [QuickStart](../quickstart.html).
创建一个项目文件夹(`attribute-directives`)并按照[快速起步](../quickstart.html)中的步骤进行初始化。
include ../_quickstart_repo
### 编写指令代码
Follow the [setup](setup.html) instructions for creating a new project
named <span ngio-ex>attribute-directives</span>.
按照[搭建](setup.html)的说明,创建一个项目文件夹<span ngio-ex>attribute-directives</span>。
:marked
Create the following source file in the indicated folder with the following code:
在指定的文件夹下创建下列源码文件:
+makeExample('app/highlight.directive.1.ts')
block highlight-directive-1
:marked
The `import` statement specifies symbols from the Angular `core`:
`import`语句指定了从Angular的`core`库导入的一些符号。
1. `Directive` provides the functionality of the `@Directive` decorator.
1. `Directive`提供`@Directive`装饰器功能。
1. `ElementRef` [injects](dependency-injection.html) into the directive's constructor
1. `ElementRef` [注入](dependency-injection.html)到指令构造函数中。
so the code can access the DOM element.
这样代码可以访问DOM元素。
1. `Input` allows data to flow from the binding expression into the directive.
1. `Input`将数据从绑定表达式传达到指令中。
1. `Renderer` allows the code to change the DOM element's style.
1. `Renderer` 让代码可以改变DOM元素的样式。
Next, the `@Directive` decorator function contains the directive metadata in a configuration object
@ -147,38 +149,38 @@ block highlight-directive-1
:marked
`@Directive` requires a CSS selector to identify
the HTML in the template that is associated with the directive.
属性型指令的`@Directive`装饰器需要一个css选择器以便从模板中识别出关联到这个指令的HTML。
The [CSS selector for an attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors)
is the attribute name in square brackets.
Here, the directive's selector is `[myHighlight]`.
Angular will locate all elements in the template that have an attribute named `myHighlight`.
[css中的attribute选择器](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors)就是属性名称加方括号。
[css中的attribute选择器](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors)就是属性名称加方括号。
这里,指令的选择器是`[myHighlight]`Angular将会在模板中找到带有`myHighlight`这个属性的元素。
.l-sub-section
:marked
### Why not call it "highlight"?
### 为什么不直接叫做"highlight"
Though *highlight* is a more concise name than *myHighlight* and would work,
a best practice is to prefix selector names to ensure
they don't conflict with standard HTML attributes.
This also reduces the risk colliding with third-party directive names.
理论上,*highlight*是一个比*myHighlight*更好的名字,而且在这里它确实能工作。
但是最佳实践是在选择器名字前面添加前缀以确保它们不会与标准HTML属性冲突。
它同时减少了与第三方指令名字发生冲突的危险。
Make sure you do **not** prefix the `highlight` directive name with **`ng`** because
that prefix is reserved for Angular and using it could cause bugs that are difficult to diagnose. For a simple demo, the short prefix, `my`, helps distinguish your custom directive.
确认你**不会**给自己的`highlight`指令添加**`ng`**前缀。
那个前缀属于Angular使用它可能导致无法检测的问题。比如这个简短的前缀`my`可以帮助你区分自定义指令。
那个前缀属于Angular使用它可能导致无法检测的问题。比如这个简短的前缀`my`可以帮助你区分自定义指令。
p
| After the #[code @Directive] metadata comes the directive's controller class, called #[code HighlightDirective], which contains the logic for the directive.
p
@ -186,7 +188,7 @@ p
+ifDocsFor('ts')
| Exporting #[code HighlightDirective] makes it accessible to other components.
+ifDocsFor('ts')
| 导出#[code HighlightDirective]以便让它可以被其它组件访问。
:marked
@ -198,18 +200,18 @@ p
Angular会为每个被指令匹配上的元素创建一个该指令控制器类的实例并把Angular的`ElementRef`和`Renderer`注入进它的构造函数。
`ElementRef`是一个服务它赋予我们直接访问DOM元素的能力。通过它的`nativeElement`属性和`Renderer`服务,我们可以设置元素的样式。
.l-main-section
a#apply-directive
:marked
## Apply the attribute directive
## 使用属性型指令
To use the new `HighlightDirective`, create a template that
applies the directive as an attribute to a paragraph (`p`) element.
In Angular terms, the `<p>` element will be the attribute **host**.
要使用这个新的`HighlightDirective`,创建一个模板,把这个指令作为属性应用到一个段落(`p`)元素上。
用Angular的话说`<p>`元素就是这个属性型指令的**宿主**。
p
@ -230,7 +232,7 @@ p
Next, add an `import` statement to fetch the `Highlight` directive and
add that class to the `declarations` NgModule metadata. This way Angular
recognizes the directive when it encounters `myHighlight` in the template.
接下来,添加了一个`import`语句来获得'Highlight'指令类,并把这个类添加到`AppComponent`组件的`declarations`数组中。
这样当Angular在模板中遇到`myHighlight`时,就能认出这是指令了。
@ -240,22 +242,22 @@ p
Now when the app runs, the `myHighlight` directive highlights the paragraph text.
运行应用,就会看到我们的指令确实高亮了段落中的文本。
figure.image-display
img(src="/resources/images/devguide/attribute-directives/first-highlight.png" alt="First Highlight")
.l-sub-section
:marked
### Your directive isn't working?
### 你的指令没生效?
Did you remember to add the directive to the the `declarations` attribute of `@NgModule`? It is easy to forget!
你记着设置`@NgModule`的`declarations`数组了吗?它很容易被忘掉。
Open the console in the browser tools and look for an error like this:
打开浏览器调试工具的控制台,会看到像这样的错误信息:
code-example(format="nocode").
EXCEPTION: Template parse errors:
@ -269,13 +271,13 @@ figure.image-display
Angular检测到你正在尝试绑定到*某些东西*,但它不认识。所以它在`declarations`元数据数组中查找。
把`HighlightDirective`列在元数据的这个数组中Angular就会检查对应的导入语句从而找到`highlight.directive.ts`,并了解`myHightlight`的功能。
:marked
To summarize, Angular found the `myHighlight` attribute on the `<p>` element. It created
an instance of the `HighlightDirective` class,
injecting a reference to the element into the constructor
where the `<p>` element's background style is set to yellow.
总结Angular在`<p>`元素上发现了一个`myHighlight`属性。
然后它创建了一个`HighlightDirective`类的实例,并把所在元素的引用注入到了指令的构造函数中。
在构造函数中,我们把`<p>`元素的背景设置为了黄色。
@ -284,22 +286,22 @@ figure.image-display
a#respond-to-user
:marked
## Respond to user-initiated events
## 响应用户引发的事件
Currently, `myHighlight` simply sets an element color.
The directive should set the color when the user hovers over an element.
当前,`myHighlight`只是简单的设置元素的颜色。
这个指令应该在用户鼠标悬浮一个元素时,设置它的颜色。
这个指令应该在用户鼠标悬浮一个元素时,设置它的颜色。
This requires two things:
我们需要:
1. detecting when the user hovers into and out of the element.
1. 检测用户的鼠标啥时候进入和离开这个元素。
2. responding to those actions by setting and clearing the highlight color.
2. 通过设置和清除高亮色来响应这些操作。
@ -307,7 +309,7 @@ a#respond-to-user
To do this, you can apply the `@HostListener` !{_decorator} to methods which are called when an event is raised.
把`host`属性加入指令的元数据中,并给它一个配置对象,用来指定两个鼠标事件,并在它们被触发时,调用指令中的方法:
+makeExample('attribute-directives/ts/app/highlight.directive.2.ts','host')(format=".")
.l-sub-section
@ -315,32 +317,32 @@ a#respond-to-user
The `@HostListener` !{_decorator} refers to the DOM element that hosts an attribute directive, the `<p>` in this case.
`@HostListener`装饰器引用的是我们这个属性型指令的宿主元素,在这个例子中就是`<p>`。
It is possible to attach event listeners by manipulating the host DOM element directly, but
可以通过直接操纵DOM元素的方式给宿主DOM元素挂上一个事件监听器但是
可以通过直接操纵DOM元素的方式给宿主DOM元素挂上一个事件监听器但是
there are at least three problems with such an approach:
但这种方法至少有三个问题:
1. You have to write the listeners correctly.
1. 必须正确的书写事件监听器。
1. The code must *detach* the listener when the directive is destroyed to avoid memory leaks.
1. 当指令被销毁的时候,必须*摘掉*事件监听器,否则就会导致内存泄露。
1. Talking to DOM API directly isn't a best practice.
1. 必须直接和DOM API打交道但正如我们学过的那样应该避免这样做。
1. 必须直接和DOM API打交道但正如我们学过的那样应该避免这样做。
:marked
Now implement the two mouse event handlers:
现在,我们实现那两个鼠标事件处理器:
+makeExample('attribute-directives/ts/app/highlight.directive.2.ts','mouse-methods')(format=".")
:marked
@ -353,9 +355,9 @@ a#respond-to-user
+makeExample('attribute-directives/ts/app/highlight.directive.2.ts','ctor')(format=".")
:marked
Here's the updated directive:
这里是更新过的指令:
+makeExample('app/highlight.directive.2.ts')
:marked
@ -363,7 +365,7 @@ a#respond-to-user
disappears as it moves out.
We run the app and confirm that the background color appears as we move the mouse over the `p` and
disappears as we move out.
运行本应用,就可以确认:当把鼠标移到`p`上的时候,背景色就出现了,而移开的时候,它消失了。
figure.image-display
img(src="/resources/images/devguide/attribute-directives/highlight-directive-anim.gif" alt="Second Highlight")
@ -371,7 +373,7 @@ figure.image-display
a#bindings
:marked
## Pass values into the directive using data binding
## 通过绑定来传递值到指令中
Currently the highlight color is hard-coded within the directive. That's inflexible.
@ -382,13 +384,13 @@ a#bindings
+makeExample('attribute-directives/ts/app/app.component.html','pHost')
:marked
You can extend the directive class with a bindable **input** `highlightColor` property and use it to highlight text.
我们将给指令类增加一个可绑定**输入**属性`highlightColor`,当需要高亮文本的时候,就用它。
Here is the final version of the class:
这里是该类的最终版:
+makeExcerpt('app/highlight.directive.ts', 'class')
a#input
@ -398,7 +400,7 @@ a#input
新的`highlightColor`属性被称为“输入”属性,这是因为数据流是从绑定表达式到这个指令的。
注意,在定义这个属性的时候,我们调用了`@Input()`#{_decoratorCn}。
+makeExcerpt('app/highlight.directive.ts', 'color')
:marked
@ -406,30 +408,30 @@ a#input
property binding under the `myHighlight` alias.
Without this input metadata Angular rejects the binding.
See the [appendix](#why-input) below for more information.
`@Input`把元数据添加到了类上,这让`highlightColor`能被以`myHighlight`为别名进行绑定。
必须添加这个input元数据否则Angular会拒绝绑定。
参见下面的[附录](#why-input)来了解为何如此。
.l-sub-section
:marked
### @Input(_alias_)
### @Input(_别名_)
Currently, the code **aliases** the `highlightColor` property with the attribute name by
passing `myHighlight` into the `@Input` #{_decorator}:
当前,代码通过将`myHighlight`传递到`@Input`装饰器,把`myHighlight`属性**别名**到属性名字上。
当前,代码通过将`myHighlight`传递到`@Input`装饰器,把`myHighlight`属性**别名**到属性名字上。
+makeExcerpt('app/highlight.directive.ts', 'color', '')
:marked
The code binds to the attribute name, `myHighlight`, but the
the directive property name is `highlightColor`. That's a disconnect.
代码绑定到`myHighlight`属性名,但是指令属性名为`highlightColor`。这是一个断点。
You can resolve the discrepancy by renaming the property to `myHighlight` and define it as follows:
你可以通过重命名属性名到`myHighlight`来移除这个区别,像这样:
+makeExcerpt('app/highlight.directive.ts', 'highlight', '')
@ -440,7 +442,7 @@ a#input
现在,通过输入型属性得到了高亮的颜色,然后修改`onMouseEnter()`来使用它代替硬编码的那个颜色名。
我们还把红色定义为默认颜色,以便在用户忘了绑定颜色时作为备用。
+makeExcerpt('attribute-directives/ts/app/highlight.directive.ts', 'mouse-enter', '')
:marked
To let users pick the highlight color and bind their choice to the directive,
@ -453,21 +455,21 @@ a#input
.l-sub-section
:marked
### Where is the templated *color* property?
### 模板的*color*属性在哪里?
You may notice that the radio button click handlers in the template set a `color` property
and the code is binding that `color` to the directive.
However, you never defined a color property for the host `AppComponent`.
Yet this code works. Where is the template `color` value going?
你可能注意到,模板中的单选按钮的点击事件处理器设置了一个`color`属性,而且把`color`绑定到指令上。
但是,你从未在这个宿主`AppComponent`中定义`color`属性,代码仍然工作正常。模板的`color`值去哪儿了?
Browser debugging reveals that Angular dynamically added a `color` property
to the runtime instance of the `AppComponent`.
在浏览器中调试就会发现Angular在`AppComponent`的运行期实例上添加了一个`color`属性。
This is *convenient* behavior but it is also *implicit* behavior that could be confusing.
@ -478,7 +480,7 @@ a#input
:marked
Here is the second version of the directive in action.
下面是指令操作演示的第二版。
figure.image-display
img(src="/resources/images/devguide/attribute-directives/highlight-directive-v2-anim.gif" alt="Highlight v.2")
@ -487,10 +489,10 @@ figure.image-display
a#second-property
:marked
## Bind to a second property
## 绑定到第二个属性
This example directive only has a single customizable property. A real app often needs more.
本例的指令只有一个可定制属性,真实的引用通常需要更多。
Let's allow the template developer to set the default color&mdash;the color that prevails until the user picks a highlight color.
@ -502,17 +504,17 @@ a#second-property
:marked
The `defaultColor` property has a setter that overrides the hard-coded default color, "red".
You don't need a getter.
`defaultColor`属性是一个setter函数它代替了硬编码的默认颜色“red”。不需要getter函数。
How do you bind to it? The app is already using `myHighlight` attribute name as a binding target.
该如何绑定到它?别忘了已经把`myHighlight`属性名用作绑定目标了。
Remember that a *component is a directive, too*.
You can add as many component property bindings as you need by stringing them along in the template
as in this example that sets the `a`, `b`, `c` properties to the string literals 'a', 'b', and 'c'.
记住,*组件也是指令*。
只要需要,就可以通过把它们依次串在模板中来为组件添加多个属性绑定。
下面这个例子中就把`a`、`b`、`c`属性设置为了字符串字面量'a', 'b', 'c'。
@ -520,7 +522,7 @@ code-example(format="." ).
&lt;my-component [a]="'a'" [b]="'b'" [c]="'c'">&lt;my-component>
:marked
The same holds true for an attribute directive.
在属性型指令中也可以这样做。
+makeExample('attribute-directives/ts/app/app.component.html', 'defaultColor')(format=".")
:marked
@ -531,7 +533,7 @@ code-example(format="." ).
我们*还*把字符串字面量'violet'绑定到了`defaultColor`上。
Here is the final version of the directive in action.
下面就是该指令最终版的操作演示。
figure.image-display
img(src="/resources/images/devguide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight")
@ -539,9 +541,9 @@ figure.image-display
.l-main-section
:marked
## Summary
## 总结
This page covered how to:
本章介绍了如何:
@ -552,7 +554,7 @@ figure.image-display
- [Respond to **events** to change behavior based on an event](#respond-to-user).
- [响应**事件**,以便基于事件改变行为](#respond-to-user)
- [Use **binding** to pass values to the attribute directive](#bindings).
- 以及[使用**绑定**来把值传给属性型指令](#bindings)。
- 以及[使用**绑定**来把值传给属性型指令](#bindings)。
The final source:
@ -579,32 +581,32 @@ a#why-input
.l-main-section
:marked
### Appendix: Input properties
### 附录Input属性
In this demo, the `highlightColor` property is an ***input*** property of
`HighlightDirective`.
本例中, `highlightColor`属性是`HighlightDirective`指令的一个***input***属性。
You've seen properties in bindings before but never had to declare them as anything. Why now?
以前也见过属性绑定,但我们从没有定义过它们。为什么现在就不行了?
Angular makes a subtle but important distinction between binding **sources** and **targets**.
Angular在绑定的**源**和**目标**之间有一个巧妙但重要的区别。
In all previous bindings, the directive or component property was a binding ***source***.
A property is a *source* if it appears in the template expression to the ***right*** of the equals (=).
在以前的所有绑定中,指令或组件的属性都是绑定***源***。
如果属性出现在了模板表达式等号(=)的***右侧***,它就是一个*源*。
A property is a *target* when it appears in **square brackets** ([ ]) to the **left** of the equals (=)
as it is does when binding to the `myHighlight` property of the `HighlightDirective`.
如果它出现在了**方括号**([ ])中,并且出现在等号(=)的**左侧**,它就是一个*目标*……
就像在绑定到`HighlightDirective`的`myHighlight`属性时所做的那样。
+makeExample('attribute-directives/ts/app/app.component.html','pHost')(format=".")
@ -612,26 +614,26 @@ a#why-input
The 'color' in `[myHighlight]="color"` is a binding ***source***.
A source property doesn't require a declaration.
`[myHighlight]="color"`中的'color'就是绑定***源***。
源属性不需要特别声明。
The 'myHighlight' in `[myHighlight]="color"` *is* a binding ***target***.
You must declare it as an *input* property or
Angular rejects the binding with a clear error.
`[myHighlight]="color"`中的'myHighlight'就是绑定***目标***。
必须把它定义为一个*Input*属性否则Angular就会拒绝这次绑定并给出一个明确的错误。
Angular treats a *target* property differently for a good reason.
A component or directive in target position needs protection.
Angular这样区别对待*目标*属性有充分的理由。
作为目标的组件或指令需要保护。
Imagine that `HighlightDirective` did truly wonderous things in a
popular open source project.
假想一下,`HighlightDirective`真是一个好东西。
我们优雅的把它当作礼物送给全世界。
@ -646,5 +648,5 @@ a#why-input
The ***input*** declaration ensures that consumers of your directive can only bind to
the properties of the public API but nothing else.
于是,这种*输入*声明可以确保指令的消费者只能绑定到公开API中的属性其它的都不行。

View File

@ -7,6 +7,21 @@ block includes
我们将持续不断的更新和改进Angular文档。本日志记录了近期最重要的变更。
## QuickStart Rewrite (2016-11-18)
## 全新《快速开始》 (2016-11-18)
The QuickStart is completely rewritten so that it actually is quick.
It references a minimal "Hello Angular" app running in Plunker.
The new [Setup](setup.html) page tells you how to install a local development environment
by downloading (or cloning) the QuickStart github repository.
You are no longer asked to copy-and-paste code into setup files that were not explained anyway.
《快速开始》被重新编写,变得更加快速。
它使用了在 Plunker 中运行的最小化的 “Hello Angular” 应用。
新添加的[搭建](setup.html)页面解释了如何通过下载或者克隆 QuickStart github 库来安装本地开发环境。
你将不再需要拷贝粘贴代码到一些并没有对其解释的配置文件中。
## Sync with Angular v.2.2.0 (2016-11-14)
## 与Angular v.2.2.0同步(2016-11-14)
@ -108,7 +123,7 @@ block includes
## 与Angular v.2.1.0同步(2016-10-12)
Docs and code samples updated and tested with Angular v.2.1.0
Docs and code samples updated and tested with Angular v.2.1.0
使用Angular v.2.1.0更新和测试所有文档和代码例子。

View File

@ -408,7 +408,7 @@ block ctor-syntax
不需要创建 Angular 注入器。
Angular 在启动过程中自动为我们创建一个应用级注入器。
+makeExample('dependency-injection/ts/app/main.ts', 'bootstrap', 'app/main.ts (excerpt)')(format='.')
+makeExcerpt('app/main.ts', 'bootstrap')
:marked
We do have to configure the injector by registering the **providers**
@ -418,24 +418,24 @@ block ctor-syntax
我们必须通过注册**提供商 (provider)** 来配置注入器,这些提供商为应用创建所需服务。
在本章的稍后部分会解释什么是[提供商](#providers)。
We can either register a provider within an [NgModule](ngmodule.html) or in application components
block register-provider-ngmodule
:marked
We can either register a provider within an [NgModule](ngmodule.html) or in application components
或者在 [NgModule](ngmodule.html) 中注册提供商,或者在应用组件中。
或者在 [NgModule](ngmodule.html) 中注册提供商,或者在应用组件中。
### Registering providers in an NgModule
### Registering providers in an NgModule
### 在 NgModule 中注册提供商
### 在 NgModule 中注册提供商
Here's our AppModule where we register a `Logger`, a `UserService`, and an `APP_CONFIG` provider.
Here's our AppModule where we register a `Logger`, a `UserService`, and an `APP_CONFIG` provider.
下面的例子是在 AppModule 中注册`Logger`、`UserService`和`APP_CONFIG`提供商。
下面的例子是在 AppModule 中注册`Logger`、`UserService`和`APP_CONFIG`提供商。
- var stylePattern = { otl: /(providers)/ };
+makeExample('dependency-injection/ts/app/app.module.ts', 'ngmodule','app/app.module.ts', stylePattern)(format='.')
<!--The preferred approach is to register application providers in application components.
Because the `HeroService` is used within the *Heroes* feature area &mdash;
and nowhere else &mdash; the ideal place to register it is in the top-level `HeroesComponent`.-->
- var app_module_ts = 'app/app.module.ts';
+makeExcerpt(app_module_ts + ' (excerpt)', 'ngmodule',app_module_ts, { otl: /(providers:)/ })
//-The preferred approach is to register application providers in application components.
//-Because the `HeroService` is used within the *Heroes* feature area &mdash;
//-and nowhere else &mdash; the ideal place to register it is in the top-level `HeroesComponent`.
:marked
### Registering providers in a component
@ -445,33 +445,34 @@ block ctor-syntax
下面是更新的`HerosComponent`,它注册了`HeroService`。
+makeExample('dependency-injection/ts/app/heroes/heroes.component.1.ts', 'full','app/heroes/heroes.component.ts', stylePattern)(format='.')
- var stylePattern = { otl: /(providers:[^,]+),/ };
+makeExample('app/heroes/heroes.component.1.ts', 'full', 'app/heroes/heroes.component.ts', stylePattern)(format='.')
:marked
### When to use the NgModule and when an application component?
### 该用 NgModule 还是应用组件?
On the one hand, a provider in an NgModule is registered in the root injector. That means that every provider
registered within an NgModule will be accessible in the entire application.
一方面NgModule 中的提供商是被注册到根注入器。这意味着在 NgModule 中注册的提供商可以被整个应用访问。
On the other hand, a provider registered in an application component is available only on that component and all its children.
另一方面,在应用组件中注册的提供商只在该组件及其子组件中可用。
We want the `APP_CONFIG` service to be available all across the application, but a `HeroService` is only used within the *Heroes*
feature area &mdash; and nowhere else. &mdash;
我们希望`APP_CONFIG`服务在整个应用中可用,而`HeroService`只需在*英雄*特性区可用,在其它地方都不可用。
.l-sub-section
block ngmodule-vs-component
:marked
Read also **Should I add app-wide providers to the root `AppModule` or the root `AppComponent`?** in the [NgModule FAQ](../cookbook/ngmodule-faq.html#root-component-or-module) chapter.
### When to use the NgModule and when an application component?
参见 [NgModule FAQ](../cookbook/ngmodule-faq.html#root-component-or-module) 一章的
**我该把“全应用级”提供商加到根模块`AppModule`还是根组件`AppComponent`**
### 该用 NgModule 还是应用组件?
On the one hand, a provider in an NgModule is registered in the root injector. That means that every provider
registered within an NgModule will be accessible in the _entire application_.
一方面NgModule 中的提供商是被注册到根注入器。这意味着在 NgModule 中注册的提供商可以被整个应用访问。
On the other hand, a provider registered in an application component is available only on that component and all its children.
另一方面,在应用组件中注册的提供商只在该组件及其子组件中可用。
We want the `APP_CONFIG` service to be available all across the application, but a `HeroService` is only used within the *Heroes*
feature area and nowhere else.
我们希望`APP_CONFIG`服务在整个应用中可用,而`HeroService`只需在*英雄*特性区可用,在其它地方都不可用。
.l-sub-section
:marked
Also see *"Should I add app-wide providers to the root `AppModule` or the root `AppComponent`?"* in the [NgModule FAQ](../cookbook/ngmodule-faq.html#root-component-or-module) .
参见 [NgModule FAQ](../cookbook/ngmodule-faq.html#root-component-or-module) 一章的
**我该把“全应用级”提供商加到根模块`AppModule`还是根组件`AppComponent`**
:marked
### Preparing the HeroListComponent for injection
@ -623,7 +624,6 @@ block ctor-syntax
现在,这个构造函数要求注入一个`Logger`类的实例,并把它存到名为`logger`的私有属性中。
当别人请求英雄数据时,在`getHeroes`方法中调用这个属性的方法。
//- FIXME refer to Dart API when that page becomes available.
- var injUrl = '../api/core/index/Injectable-decorator.html';
h3#injectable Why @Injectable()?
h3#injectable 为什么要用 @Injectable()?
@ -662,7 +662,7 @@ block injectable-not-always-needed-in-ts
li
p <b>Future proofing:</b> No need to remember <code>@Injectable()</code> when we add a dependency later.
p <b>面向未来:</b> 没有必要记得在后来添加依赖的时候添加 <code>@Injectable()</code>。
li
li
p <b>Consistency:</b> All services follow the same rules, and we don't have to wonder why #{_a} #{_decorator} is missing.
p <b>一致性:</b>所有的服务都遵循同样的规则,不需要考虑为什么某个地方少了一个。
@ -747,7 +747,7 @@ block injectable-not-always-needed-in-ts
这个日志服务很简单:
+makeExample('dependency-injection/ts/app/logger.service.ts', null, 'app/logger.service.ts')
+makeExample('app/logger.service.ts')
block real-logger
//- N/A
@ -755,12 +755,12 @@ block real-logger
:marked
We're likely to need the same logger service everywhere in our application,
so we put it in the project's `#{_appDir}` folder, and
we register it in the `providers` #{_array} of the metadata for our application module, `AppModule`.
we register it in the `providers` #{_array} of our application !{_moduleVsComp}, `!{_AppModuleVsAppComp}`.
应用的每个角落都可能需要日志服务,所以把它放到项目的`#{_appDir}`目录,
并在应用模块`AppModule`的元数据`providers`数组里注册它。
+makeExcerpt('app/providers.component.ts','providers-logger','app/app.module.ts (excerpt)')
+makeExcerpt('app/providers.component.ts (excerpt)', 'providers-logger','app/app.module.ts')
:marked
If we forget to register the logger, Angular throws an exception when it first looks for the logger:
@ -873,7 +873,7 @@ block provider-ctor-args
第一个是[令牌 (token)](#token),它作为键值 (key) 使用,用于定位依赖值和注册提供商。
The second is a !{_secondParam},
The second is a !{_secondParam},
which we can think of as a *recipe* for creating the dependency value.
There are many ways to create dependency values ... and many ways to write a recipe.
@ -1226,9 +1226,8 @@ block what-should-we-use-as-token
这不是 Angular 的错。接口只是 TypeScript 设计时 (design-time) 的概念。JavaScript 没有接口。
TypeScript 接口不会出现在生成的 JavaScript 代码中。
在运行期,没有接口类型信息可供 Angular 查找。
// end Typescript only
//- FIXME simplify once APIs are defined for Dart.
//- FIXME update once https://github.com/dart-lang/angular2/issues/16 is addressed.
- var opaquetoken = _docsFor == 'dart' ? '<b>OpaqueToken</b>' : '<a href="../api/core/index/OpaqueToken-class.html"><b>OpaqueToken</b></a>'
:marked
### OpaqueToken

View File

@ -51,14 +51,13 @@ figure.image-display
要显示组件的属性最简单的方式就是通过插值表达式interpolation来绑定属性名。
要使用插值表达式,就把属性名包裹在双花括号里放进视图模板,如`{{myHero}}`。
To build an illustrative example, start by creating a new project folder called <ngio-ex path="displaying-data"></ngio-ex>
and following the steps in [QuickStart](../quickstart.html).
Follow the [setup](setup.html) instructions for creating a new project
named <ngio-ex path="displaying-data"></ngio-ex>.
我们来一起做个简明的小例子。创建一个新的项目文件夹(<ngio-ex path="displaying-data"></ngio-ex>),并且完成[“快速起步”](../quickstart.html)中的步骤
按照[搭建](setup.html)的说明,创建一个新项目,名为<ngio-ex path="displaying-data"></ngio-ex>。
:marked
Then modify the <ngio-ex path="app.component.ts"></ngio-ex> file by
changing the template and the body of the component.
changing the template and the body of the component.
然后,到`app.component.ts`文件中修改组件的模板和代码。
@ -101,7 +100,7 @@ figure.image-display
.l-sub-section
:marked
More precisely, the redisplay occurs after some kind of asynchronous event related to
the view, such as a keystroke, a timer completion, or a response to an HTTP request.
the view, such as a keystroke, a timer completion, or a response to an HTTP request.
严格来说“重新显示”是在某些与视图有关的异步事件之后发生的比如按键、定时器完成或对HTTP请求的响应。
@ -111,12 +110,11 @@ figure.image-display
注意,我们从没调用过**new**来创建`AppComponent`类的实例是Angular替我们创建了它。那么它是如何创建的呢
The CSS `selector` in the `@Component` !{_decorator} specifies an element named `my-app`.
Remember back in [QuickStart](../quickstart.html) that you added the `<my-app>`
element to the body of your `index.html` file:
The CSS `selector` in the `@Component` !{_decorator} specifies an element named `<my-app>`.
That element is a placeholder in the body of your `index.html` file:
注意`@Component`装饰器中指定的CSS选择器`selector`,它指定了一个叫`my-app`的元素。
回忆下,在[“快速起步”](../quickstart.html)一章中,我们曾把一个`<my-app>`元素添加到`index.html`的`body`里
该元素是`index.html`的`body`里的占位符
+makeExcerpt('index.html', 'body')
@ -217,7 +215,7 @@ figure.image-display
.alert.is-important
:marked
Don't forget the leading asterisk (\*) in `*ngFor`. It is an essential part of the syntax.
For more information, see the [Template Syntax](./template-syntax.html#ngFor) page.
For more information, see the [Template Syntax](./template-syntax.html#ngFor) page.
不要忘记`*ngFor`中的前导星号(\*)。它是语法中不可或缺的一部分。
要了解关于此语法和`ngFor`的更多知识,请参见[模板语法](./template-syntax.html#ngFor)一章。

View File

@ -15,13 +15,13 @@ include ../_util-fns
但是,要想做出具有贴心的数据输入体验的表单,
引导用户明晰、高效地完成表单背后的工作流程,挑战就大多了。
*That* takes design skills that are, to be frank, well out of scope for this chapter.
*That* takes design skills that are, to be frank, well out of scope for this guide.
坦白地讲,*这当中*所需要的设计技能超出了本章的范围。
It also takes framework support for
**two-way data binding, change tracking, validation, and error handling**
... which we shall cover in this chapter on Angular forms.
... which we shall cover in this guide on Angular forms.
**双向数据绑定、变更跟踪、有效性验证和错误处理**等功能离不开框架的支持。
本章将介绍Angular表单相关的内容。
@ -65,16 +65,14 @@ include ../_util-fns
## 模板驱动的表单
Many of us will build forms by writing templates in the Angular [template syntax](./template-syntax.html) with
the form-specific directives and techniques described in this chapter.
the form-specific directives and techniques described in this guide.
通常使用Angular[模板语法](./template-syntax.html)编写模板,结合本章所描述的表单专用指令和技术来构建表单。
.l-sub-section
:marked
That's not the only way to create a form but it's the way we'll cover in this chapter.
That's not the only way to create a form but it's the way we'll cover in this guide.
这不是创建表单的唯一方式,本章中只介绍模板驱动的表单。(译注Angular支持的另一种方式叫做模型驱动表单Model-Driven Forms)
:marked
We can build almost any form we need with an Angular template &mdash; login forms, contact forms ... pretty much any business forms.
We can lay out the controls creatively, bind them to data, specify validation rules and display validation errors,
@ -170,12 +168,11 @@ figure.image-display
## 搭建
Create a new project folder (`angular-forms`) and follow the steps in the [QuickStart](../quickstart.html).
Follow the [setup](setup.html) instructions for creating a new project
named <span ngio-ex>angular-forms</span>.
创建新的项目文件夹 (`angular-forms`),并且完成[“快速起步”](../quickstart.html)中的步骤
按照[搭建](setup.html)的说明,创建一个名为<span ngio-ex>angular-forms</span>的新项目
include ../_quickstart_repo
:marked
## Create the Hero Model Class
## 创建Hero模型类
@ -229,13 +226,14 @@ code-example(format="").
## 创建表单组件
An Angular form has two parts: an HTML-based template and a code-based Component to handle data and user interactions.
An Angular form has two parts: an HTML-based _template_ and a component _class_
to handle data and user interactions programmatically.
Angular 表单分为两部分:基于 HTML 的模板和基于代码的组件。组件用来处理数据和用户交互。
Angular 表单分为两部分:基于 HTML 的*模板*和组件*类*,用来程序处理数据和用户交互。
We begin with the Component because it states, in brief, what the Hero editor can do.
We begin with the class because it states, in brief, what the hero editor can do.
先从组件开始,是因为它可以简要说明英雄编辑器能做什么。
先从组件开始,是因为它可以简要说明英雄编辑器能做什么。
Create a new file called `hero-form.component.ts` and give it the following definition:
@ -248,7 +246,7 @@ code-example(format="").
这个组件没有什么特别的地方,没有表单相关的东西,与之前写过的组件没什么不同。
Understanding this component requires only the Angular concepts weve learned in previous chapters
Understanding this component requires only the Angular concepts weve learned in previous guides
只需要前面章节中学过的概念,就可以完全理解这个组件:
@ -288,10 +286,13 @@ code-example(format="").
在最后增加`diagnostic`属性它返回这个模型的JSON形式。
在开发过程中,它用于调试,最后清理时会丢弃它。
Why don't we write the template inline in the component file as we often do
elsewhere in the Developer Guide?
### Why the separate template file?
这次为什么不像在开发指南其它地方那样,以内联的方式把模板写在组件文件中呢?
### 为何分离模板文件?
Why don't we write the template inline in the component file as we often do elsewhere?
为什么不与我们在其他地方常常做的那样,以内联的方式把模板写在组件文件中呢?
There is no “right” answer for all occasions. We like inline templates when they are short.
Most form templates won't be short. TypeScript and JavaScript files generally aren't the best place to
@ -303,12 +304,13 @@ code-example(format="").
而且没有几个编辑器能对混写的 HTML 和代码提供足够的帮助。
我们还是喜欢内容清晰、目标明确的短文件,像这个一样。
We made a good choice to put the HTML template elsewhere.
We'll write that template in a moment. Before we do, we'll take a step back
and revise the `app.module.ts` and `app.component.ts` to make use of our new `HeroFormComponent`.
Form templates tend to be quite large even when displaying a small number of fields
so it's usually best to put the HTML template in a separate file.
We'll write that template file in a moment. Before we do, we'll take a step back
and revise the `app.module.ts` and `app.component.ts` to make use of the new `HeroFormComponent`.
把 HTML 模板放在其它地方是个不错的选择。等会儿就去写那个模板
在这之前,先回来修改`app.module.ts`和`app.component.ts`文件,用上新写的`HeroFormComponent`组件
就算是在仅仅显示少数表单项目时表单模板一般都比较庞大。所以通常最好的方式是将HTML模板放到单独的文件中
一会儿将编写这个模板文件。在这之前,先退一步,再看看`app.module.ts`和`app.component.ts`,让它们使用新的`HeroFormComponent`
.l-main-section
:marked
@ -354,7 +356,7 @@ code-example(format="").
.alert.is-important
:marked
If a component, directive, or pipe belongs to a module in the `imports` array, _DON'T_ declare it in the `declarations` array.
If a component, directive, or pipe belongs to a module in the `imports` array, _DON'T_ re-declare it in the `declarations` array.
If you wrote it and it should belong to this module, _DO_ declare it in the `declarations` array.
如果组件、指令或管道出现在模块的`imports`数组中_不要_把它声明在`declarations`数组中。
@ -378,9 +380,9 @@ code-example(format="").
:marked
.l-sub-section
:marked
There is only one change:
There is only one change.
仅有的一处修改是:
仅有的一处修改
1. The `template` is simply the new element tag identified by the component's `selector` property.
This will display the hero form when the application component is loaded.
@ -420,8 +422,7 @@ code-example(format="").
The `container`, `form-group`, `form-control`, and `btn` classes
come from [Twitter Bootstrap](http://getbootstrap.com/css/). Purely cosmetic.
We're using Bootstrap to gussy up our form.
Hey, what's a form without a little style!
We're using Bootstrap to give the form a little style!
`container`、`form-group`、`form-control`和`btn`类来自 [Twitter Bootstrap](http://getbootstrap.com/css/)。纯粹是装饰。
我们使用 Bootstrap 来美化表单。嘿,一点样式都没有的表单算个啥!
@ -474,7 +475,7 @@ ol
We'll add a `select` to our
form and bind the options to the `powers` list using `ngFor`,
a technique we might have seen before in the [Displaying Data](./displaying-data.html) chapter.
a technique seen previously in the [Displaying Data](./displaying-data.html) guide.
在表单中添加`select`,用`ngFor`把`powers`列表绑定到列表选项。
我们在之前的[显示数据](./displaying-data.html)一章中见过`ngFor`。
@ -486,7 +487,7 @@ ol
:marked
We are repeating the `<options>` tag for each power in the list of Powers.
The `p` template input variable is a different power in each iteration;
The `pow` template input variable is a different power in each iteration;
we display its name using the interpolation syntax with the double-curly-braces.
列表中的每一项超能力都会渲染成`<option>`标签。
@ -495,10 +496,9 @@ ol
<a id="ngModel"></a>
.l-main-section
:marked
## Two-way data binding with **ngModel**
## 使用 **ngModel** 进行双向数据绑定
## Two-way data binding with **_ngModel_**
## 使用 ***ngModel*** 进行双向数据绑定
Running the app right now would be disappointing.
如果立即运行此应用,你将会失望。
@ -507,7 +507,7 @@ figure.image-display
img(src="/resources/images/devguide/forms/hero-form-3.png" width="400px" alt="没有数据绑定的早期表单")
:marked
We don't see hero data because we are not binding to the `Hero` yet.
We know how to do that from earlier chapters.
We know how to do that from earlier guides.
[Displaying Data](./displaying-data.html) taught us Property Binding.
[User Input](./user-input.html) showed us how to listen for DOM events with an
Event Binding and how to update a component property with the displayed value.
@ -532,7 +532,7 @@ figure.image-display
找到“Name”对应的`<input>`标签,并且像这样修改它:
+makeExample('forms/ts/app/hero-form.component.html', 'ngModel-1','app/hero-form.component.html (节选)')(format=".")
+makeExample('forms/ts/app/hero-form.component.html', 'ngModelName-1','app/hero-form.component.html (节选)')(format=".")
.l-sub-section
:marked
@ -575,7 +575,7 @@ figure.image-display
:marked
Internally Angular creates `FormControls` and registers them with an `NgForm` directive that Angular
attached to the `<form>` tag. Each `FormControl` is registered under the name we assigned to the `name` attribute.
We'll talk about `NgForm` [later in this chapter](#ngForm).
We'll talk about `NgForm` [later in this guide](#ngForm).
在内部Angular 创建了一些`FormControl`,并把它们注册到`NgForm`指令,再将该指令附加到`<form>`标签。
注册每个`FormControl`时,使用`name`属性值作为键值。[本章后面](#ngForm)会讨论`NgForm`。
@ -584,7 +584,7 @@ figure.image-display
Let's add similar `[(ngModel)]` bindings and `name` attributes to *Alter Ego* and *Hero Power*.
We'll ditch the input box binding message
and add a new binding at the top to the component's `diagnostic` property.
Then we can confirm that two-way data binding works *for the entire Hero model*.
Then we can confirm that two-way data binding works *for the entire hero model*.
为*第二人格*和*超能力*属性添加类似的`[(ngModel)]`绑定和`name`属性。
抛弃输入框的绑定消息,在组件顶部添加到`diagnostic`属性的新绑定。
@ -609,7 +609,7 @@ figure.image-display
每个 input 元素都有`name`属性Angular 表单用它注册控件。
:marked
If we ran the app right now and changed every Hero model property, the form might display like this:
If we ran the app right now and changed every hero model property, the form might display like this:
如果现在运行本应用,修改 Hero 模型的每个属性,表单看起来像这样:
figure.image-display
@ -626,43 +626,43 @@ figure.image-display
.l-sub-section
:marked
### Inside [(ngModel)]
### Inside _[(ngModel)]_
### [(ngModel)]内幕
### [(ngModel)]内幕
*This section is an optional deep dive into [(ngModel)]. Not interested? Skip ahead!*
*This section is an optional deep dive into [(ngModel)]. Not interested? Skip ahead!*
*本节是对[(ngModel)]的深入剖析,它是可选的。不感兴趣?跳过它!*
*本节是对[(ngModel)]的深入剖析,它是可选的。不感兴趣?跳过它!*
The punctuation in the binding syntax, <span style="font-family:courier"><b>[()]</b></span>, is a good clue to what's going on.
The punctuation in the binding syntax, <span style="font-family:courier"><b>[()]</b></span>, is a good clue to what's going on.
绑定语法中的<span style="font-family:courier"><b>[()]</b></span>是很好的线索。
绑定语法中的<span style="font-family:courier"><b>[()]</b></span>是很好的线索。
In a Property Binding, a value flows from the model to a target property on screen.
We identify that target property by surrounding its name in brackets, <span style="font-family:courier"><b>[]</b></span>.
This is a one-way data binding **from the model to the view**.
In a Property Binding, a value flows from the model to a target property on screen.
We identify that target property by surrounding its name in brackets, <span style="font-family:courier"><b>[]</b></span>.
This is a one-way data binding **from the model to the view**.
在属性绑定中,值从模型中流动到屏幕上的目标属性 (property)。
通过把属性名括在方括号中来标记出目标属性,<span style="font-family:courier"><b>[]</b></span>。
这是**从模型到视图**的单向数据绑定。
在属性绑定中,值从模型中流动到屏幕上的目标属性 (property)。
通过把属性名括在方括号中来标记出目标属性,<span style="font-family:courier"><b>[]</b></span>。
这是**从模型到视图**的单向数据绑定。
In an Event Binding, we flow the value from the target property on screen to the model.
We identify that target property by surrounding its name in parentheses, <span style="font-family:courier"><b>()</b></span>.
This is a one-way data binding in the opposite direction **from the view to the model**.
In an Event Binding, we flow the value from the target property on screen to the model.
We identify that target property by surrounding its name in parentheses, <span style="font-family:courier"><b>()</b></span>.
This is a one-way data binding in the opposite direction **from the view to the model**.
在事件绑定中,值从屏幕上的目标属性流动到模型。
通过把属性名括在圆括号中来标记出目标属性,<span style="font-family:courier"><b>()</b></span>。
这是**从视图到模型**的反向单向数据绑定。
在事件绑定中,值从屏幕上的目标属性流动到模型。
通过把属性名括在圆括号中来标记出目标属性,<span style="font-family:courier"><b>()</b></span>。
这是**从视图到模型**的反向单向数据绑定。
No wonder Angular chose to combine the punctuation as <span style="font-family:courier"><b>[()]</b></span>
to signify a two-way data binding and a **flow of data in both directions**.
No wonder Angular chose to combine the punctuation as <span style="font-family:courier"><b>[()]</b></span>
to signify a two-way data binding and a **flow of data in both directions**.
不出所料Angular选择了组合标点 <span style="font-family:courier"><b>[()]</b></span> 来标记出双向数据绑定和**双向数据流**。
不出所料Angular选择了组合标点 <span style="font-family:courier"><b>[()]</b></span> 来标记出双向数据绑定和**双向数据流**。
In fact, we can break the `NgModel` binding into its two separate modes
as we do in this re-write of the "Name" `<input>` binding:
In fact, we can break the `NgModel` binding into its two separate modes
as we do in this re-write of the "Name" `<input>` binding:
事实上,可以把`NgModel`绑定拆成两个独立的绑定就像下面重写的“Name”`<input>`绑定一样:
事实上,可以把`NgModel`绑定拆成两个独立的绑定就像下面重写的“Name”`<input>`绑定一样:
+makeExample('forms/ts/app/hero-form.component.html', 'ngModel-3','app/hero-form.component.html (excerpt)')(format=".")
:marked
@ -699,13 +699,13 @@ figure.image-display
只有当需要在事件处理函数中做一些特别的事情(比如合并或限制按键频率)时,才会拆分出独立的事件处理函数。
Learn more about `NgModel` and other template syntax in the
[Template Syntax](./template-syntax.html) chapter.
[Template Syntax](./template-syntax.html) guide.
要学习`ngModel`和其它模板语法的更多知识,见[模板语法](./template-syntax.html)。
.l-main-section
:marked
## Track change-state and validity with **ngModel**
## Track change-state and validity with **_ngModel_**
## 通过 **ngModel** 跟踪修改状态与有效性验证
@ -917,7 +917,7 @@ figure.image-display
现在,把`div`元素的`hidden`属性绑定到`name`控件的属性,这样就可以控制“姓名”字段错误信息的可见性了。
+makeExample('forms/ts/app/hero-form.component.html',
'hidden-error-msg',
'app/hero-form.component.html (节选)')
'app/hero-form.component.html (节选)')(format='.')
:marked
In this example, we hide the message when the control is valid or pristine;
pristine means the user hasn't changed the value since it was displayed in this form.
@ -942,7 +942,7 @@ figure.image-display
如果当控件是“全新”状态时也隐藏消息,就能达到这个目的。
在往表单中[添加新英雄](#new-hero)时,将看到这种选择的重要性。
The Hero *Alter Ego* is optional so we can leave that be.
The hero *Alter Ego* is optional so we can leave that be.
英雄的*第二人格*是可选项,所以不用改它。
@ -964,17 +964,18 @@ figure.image-display
## 添加英雄及重置表单
We'd like to add a new hero in this form.
We place a "New Hero" button at the bottom of the form and bind its click event to a component method.
We place a "New Hero" button at the bottom of the form and bind its click event to a `newHero` component method.
我们希望在这个表单中添加新的英雄。
在表单的底部放置“New Hero新增英雄”按钮并把它的点击事件绑定到组件方法。
在表单的底部放置“New Hero新增英雄”按钮并把它的点击事件绑定到`newHero`组件。
+makeExample('forms/ts/app/hero-form.component.html',
'new-hero-button',
'new-hero-button-no-reset',
'app/hero-form.component.html (新增英雄按钮)')
:marked
+makeExample('forms/ts/app/hero-form.component.ts',
'new-hero-v1',
'app/hero-form.component.ts (新增英雄按钮 - v1)')(format=".")
'new-hero',
'app/hero-form.component.ts (新英雄方法)')(format=".")
:marked
Run the application again, click the *New Hero* button, and the form clears.
The *required* bars to the left of the input box are red, indicating invalid `name` and `power` properties.
@ -987,59 +988,39 @@ figure.image-display
错误信息是隐藏的,因为表单还是全新的,还没有修改任何东西。
Enter a name and click *New Hero* again.
This time we see an error message! Why? We don't want that when we display a new (empty) hero.
The app displays a **_Name is required_** error message!
We don't want error messages when we create a new (empty) hero.
Why are we getting one now?
输入名字,再次点击 *New Hero* 按钮。
这次,出现了错误信息!为什么?我们不希望显示新(空)的英雄时,出现错误信息。
Inspecting the element in the browser tools reveals that the *name* input box is no longer pristine.
Replacing the hero *did not restore the pristine state* of the control.
Inspecting the element in the browser tools reveals that the *name* input box is _no longer pristine_.
The form remembers that we entered a name before clicking *New Hero*.
Replacing the hero *did not restore the pristine state* of the form controls.
使用浏览器工具审查这个元素就会发现,这个*name*输入框并不是全新的。
表单记得我们在点击*New Hero*前输入的名字。
更换了英雄*并不会重置控件的“全新”状态*。
.l-sub-section
:marked
Upon reflection, we realize that Angular cannot distinguish between
replacing the entire hero and clearing the `name` property programmatically.
Angular makes no assumptions and leaves the control in its current, dirty state.
沉思一番你会发现Angular 没办法区分是替换了整个英雄数据还是用程序清除了`name`属性。
Angular 不能作出假设,只好让控件保留当前状态 —— 脏状态。
:marked
We'll have to reset the form controls manually with a small trick.
We add an `active` flag to the component, initialized to `true`. When we add a new hero,
we toggle `active` false and then immediately back to true with a quick `setTimeout`.
We have to clear all of the flags imperatively which we can do
by calling the form's `reset()` method after calling the `newHero()` method.
可以用个小花招来重置表单控件。
给组件添加`active`标记,初始化为`true`。当添加新的英雄时,把`active`标记设置为`false`
再通过快速的`setTimeout`函数迅速把它设置回`true`。
+makeExample('forms/ts/app/hero-form.component.ts',
'new-hero',
'app/hero-form.component.ts (新增英雄 - 最终版)')(format=".")
:marked
Then we bind the form element to this `active` flag.
我们必须清除所有标记,在调用`newHero()`方法后调用表单的`reset()`方法即可。
然后,把 form 元素绑定到这个`active`标志。
+makeExample('forms/ts/app/hero-form.component.html',
'form-active',
'app/hero-form.component.html (Form标签)')
'new-hero-button-form-reset',
'app/hero-form.component.html (Reset the form)')
:marked
With `NgIf` bound to the `active` flag,
clicking "New Hero" removes the form from the DOM and recreates it in a blink of an eye.
The re-created form is in a pristine state. The error message is hidden.
Now clicking "New Hero" both resets the form and its control flags.
因为`NgIf`绑定到`active`标志,点击 "New Hero" 将从DOM中移除这个表单并在一眨眼的功夫重建它。
重新创建的表单处于“全新”状态。错误信息被隐藏了。
.l-sub-section
:marked
This is a temporary workaround while we await a proper form reset feature.
这只是临时的变通方案,将来会用更好的方式来重置表单。
现在点击“New Hero”重设表单和它的控制标记。
:marked
.l-main-section
:marked
## Submit the form with **ngSubmit**
## Submit the form with **_ngSubmit_**
## 使用 **ngSubmit** 提交表单
@ -1072,10 +1053,9 @@ figure.image-display
<a id="ngForm"></a>
.l-sub-section
:marked
### The NgForm directive
### The _NgForm_ directive
### NgForm指令
What `NgForm` directive? We didn't add an [NgForm](../api/forms/index/NgForm-directive.html) directive!
什么`NgForm`指令?之前没有添加过[NgForm](../api/common/index/NgForm-directive.html)指令啊!
@ -1144,7 +1124,7 @@ figure.image-display
jazzing it up won't teach us anything new about forms.
But this is an opportunity to exercise some of our newly won
binding skills.
If you're not interested, you can skip to the chapter's conclusion
If you're not interested, you can skip to the guide's conclusion
and not miss a thing.
对演示来说,这个收场很平淡的。老实说,即使让它更出彩,也无法教给我们任何关于表单的新知识。
@ -1214,7 +1194,7 @@ figure.image-display
## 结论
The Angular form techniques discussed in this chapter take
The Angular form techniques discussed in this guide take
advantage of the following framework features to provide support for data modification, validation and more:
本章讨论的 Angular 表单技术利用了下列框架特性来支持数据修改、验证和更多操作:

View File

@ -1,18 +1,26 @@
block includes
include ../_util-fns
- var _angular_io = 'angular.cn';
- var __lang = _docsFor || current.path[1] || 'ts';
- var guideData = public.docs[__lang].latest.guide._data;
- var advancedLandingPage = '';
- for(var page in guideData) {
- if (!guideData[page].basics && !guideData[page].hide) { advancedLandingPage = page; break; }
- }
- var advancedUrl = './' + advancedLandingPage + '.html'
figure
img(src="/resources/images/devguide/intro/people.png" alt="Us" align="left" style="width:200px; margin-left:-40px;margin-right:10px")
:marked
This is a practical guide to Angular for experienced programmers who
are building client applications in HTML and #{_Lang}. <br class="l-clear-left">
This page describes the Angular documentation at a high level.
If you're new to Angular, you may want to visit "[Learning Angular](learning-angular.html)" first.
这是一份Angular实战指南。面向的是正在用HTML和#{langName}构建客户端应用的、有经验的程序员。
本页是Angular文档的概述。
如果你刚接触 Angular请先访问"[学习 Angular](learning-angular.html)"。
## Organization
## Themes
## 组织结构
## 文档结构
The documentation is divided into major thematic sections, each
a collection of pages devoted to that theme.
@ -38,31 +46,36 @@ table(width="100%")
p <b><a href="../quickstart.html">快速起步</a></b>
td
:marked
The foundation for every page and sample in this documentation.
A first taste of Angular<span if-docs="ts"> with zero installation.
Run "Hello World" in an online code editor and start playing with live code</span>.
<span if-docs="ts">零配置第一次尝试 Angular </span><span if-docs="ts">在在线代码编辑器中运行“Hello World”并利用在线代码开始体验</span>。
本文档中每一个页面和范例的基础工作。
tr(style=top)
td
p <b><a href="./">Guide</a></b>
p <b><a href="./">指南</a></b>
td
:marked
The essential ingredients of Angular development.
Learn the Angular basics (you're already here!) like the setup for local development,
displaying data and accepting user input, injecting application services into components,
and building simple forms.
Angular开发中必不可少的要素。
学习 Angular 基础知识(你已经在这儿了!),比如搭建本地开发环境、显示数据和接受用户输入、注入应用程序服务到组件中,
以及构建简单表单。
tr(style=top)
td
p <b><a href="../api">API Reference</a></b>
p <b><a href="../api">API参考手册</a></b>
p <b><a href="../api/">API Reference</a></b>
p <b><a href="../api/">API参考手册</a></b>
td
:marked
Authoritative details about each member of the Angular libraries.
Authoritative details about each of the Angular libraries.
关于Angular库中每一个成员的详尽、权威的资料。
tr(style=top)
td
p <b><a href="../tutorial">Tutorial</a></b>
p <b><a href="../tutorial">教程</a></b>
p <b><a href="../tutorial/">Tutorial</a></b>
p <b><a href="../tutorial/">教程</a></b>
td
:marked
A step-by-step, immersive approach to learning Angular that
@ -81,8 +94,8 @@ table(width="100%")
深入分析Angular的特性和开发实践。
tr(style=top)
td
p <b><a href="../cookbook">Cookbook</a></b>
p <b><a href="../cookbook">烹饪宝典</a></b>
p <b><a href="../cookbook/">Cookbook</a></b>
p <b><a href="../cookbook/">烹饪宝典</a></b>
td
:marked
Recipes for specific application challenges, mostly code snippets with a minimum of exposition.
@ -90,112 +103,58 @@ table(width="100%")
一组解决实际应用中某些特定挑战的“菜谱”,大部分是代码片段随带少量的详细阐述。
:marked
## Learning path
## 学习路径
You don't have to read the guide straight through. Most pages stand on their own.
我们不需要从头到尾依次阅读本指南。大部分页面都是独立的。
For those new to Angular, the recommended learning path runs through the *Guide* section:
对于Angular新手建议的学习路径是走完“指南”区
1. For the big picture, read the [Architecture](architecture.html) overview.
1. 要了解全景图,请阅读[架构](architecture.html)概览。
1. Try [QuickStart](../quickstart.html). QuickStart is the "Hello, World" of Angular.
It shows you how to set up the libraries and tools you'll need to write *any* Angular app.
1. 试用[“快速起步”](../quickstart.html)。“快速起步”是Angular的“Hello, World”。
它会告诉我们如何设置*任何*Angular应用程序都会用到的库和工具。
1. Take the *Tour of Heroes* [tutorial](../tutorial), which picks up where QuickStart leaves off,
and builds a simple data-driven app. The app demonstrates the essential characteristics of a professional application:
a sensible project structure, data binding, master/detail, services, dependency injection, navigation, and remote data access.
1. 学习*英雄指南*[教程](../tutorial) ,它将从“快速起步”出发,最终构建出一个简单的数据驱动的应用。
它虽简单,但也具有我们写一个专业应用时所需的一切基本特性:
实用的项目结构、数据绑定、主从视图、服务、依赖注入、导航,以及远程数据访问。
1. [Displaying Data](displaying-data.html) explains how to display information on the screen.
1. [显示数据](displaying-data.html)解释了如何把信息显示到屏幕上。
1. [User Input](user-input.html) covers how Angular responds to user behavior.
1. [用户输入](user-input.html)解释了Angular如何响应用户行为。
1. [Forms](forms.html) handles user data entry and validation within the UI.
1. [表单](forms.html)用来在UI中处理用户输入的数据并进行有效性验证。
1. [Dependency Injection](dependency-injection.html) is the way to build large, maintainable applications
from small, single-purpose parts.
1. [依赖注入](dependency-injection.html)是我们把小型、单一用途的部件组装成大型、可维护的应用的方法。
1. [Template Syntax](template-syntax.html) is a comprehensive study of Angular template HTML.
1. [模板语法](template-syntax.html)是对Angular模板HTML的全面讲解。
After reading the above sections, you can skip to any other pages on this site.
读完这些,你就可以跳到本网站的任意页面去阅读了。
## Code samples
## 代码范例
Each page includes code snippets that you can reuse in your applications.
These snippets are excerpts from a sample application that accompanies the page.
每个页面都包含一些能在我们自己的应用中复用的代码片段。
这些片段来自于相应页面中附带的范例应用。
Look for a link to a running version of that sample near the top of each page,
such as this <live-example name="architecture"></live-example> from the [Architecture](architecture.html) page.
在每页靠近顶部的地方都可以看到一个链接,指向这个范例的可执行版本,比如[架构](architecture.html)一章中的<live-example name="architecture"></live-example>。
<p if-docs="ts">
The link launches a browser-based code editor where you can inspect, modify, save, and download the code.
</p>
<p if-docs="ts">
这个链接启动一个基于浏览器的代码编辑器,在这里,我们可以查看、修改、保存和下载这些代码。
</p>
A few early pages are written as tutorials and are clearly marked as such.
The rest of the pages highlight key points in code rather than explain each step necessary to build the sample.
You can always get the full source through the #{_liveLink}.
You can always get the full source through the #{_liveLink}s.
少量早期页面是作为教程来写的,并被清晰的标注出来。
其它页面的目的是展示代码中的关键点,而不是解释构建这个范例所需的每一个步骤。
我们可以通过在线例子的链接找到完整的源代码。
## Code samples
Each page includes code snippets from a sample application that accompanies the page.
You can reuse these snippets in your applications.
Look for a link to a running version of that sample, often near the top of the page,
such as this <live-example name="architecture"></live-example> from the [Architecture](architecture.html) page.
<span if-docs="ts">
The link launches a browser-based, code editor where you can inspect, modify, save, and download the code.
</span>
## Reference pages
## 参考资料
- The [Cheat Sheet](cheatsheet.html) lists Angular syntax for common scenarios.
* The [Cheat Sheet](cheatsheet.html) lists Angular syntax for common scenarios.
- [速查表](cheatsheet.html)列出了Angular在常见场景下的语法。
* [速查表](cheatsheet.html)列出了Angular在常见场景下的语法。
- The [Glossary](glossary.html) defines terms that Angular developers should know.
* The [Glossary](glossary.html) defines terms that Angular developers should know.
- [词汇表](glossary.html)定义了Angular开发者需要知道的术语。
* [词汇表](glossary.html)定义了Angular开发者需要知道的术语。
- The [API Reference](../api/) is the authority on every public-facing member of the Angular libraries.
<li if-docs="ts">The [Change Log](change-log.html) announces what's new and changed in the documentation.</li>
- [API参考手册](../api/)是关于Angular库中每一个公有成员的权威参考资料。
<li if-docs="ts">The [变更日志](change-log.html) 宣布文档新增与更新内容</li>
## We welcome feedback!
## 我们期待您的反馈!
* The [API Reference](../api/) is the authority on every public-facing member of the Angular libraries.
- Use the [website GitHub repo](!{_ngDocRepoURL}) for **documentation** issues and pull requests.
* [API参考手册](../api/)是关于Angular库中每一个公有成员的权威参考资料。
- 到[angular.io Github库](https://github.com/angular/angular.io)提交**文档相关**的issues和pull requests.
## Feedback
- Use the [Angular GitHub repo](!{_ngRepoURL}) to report issues with **Angular** itself.
## 反馈
We welcome feedback!
我们期待您的反馈!
* Use the <a href="!{_ngDocRepoURL}" target="_blank" title="angular docs on github">!{_angular_io} Github repository</a> for **documentation** issues and pull requests.
* 到<a href="!{_ngDocRepoURL}" target="_blank" title="angular docs on github">!{_angular_io} Github 库</a>提交**文档相关**的issues和pull requests.
* Use the <a href="!{_ngRepoURL}" target="_blank" title="angular source on github">Angular Github repository</a> to report issues with **Angular** itself.
- 到<a href="!{_ngRepoURL}" target="_blank" title="angular source on github">Angular Github 库</a>报告与**Angular本身**有关的issues。
- 到[Angular Github库](https://github.com/angular/angular)报告与**Angular本身**有关的issues。

View File

@ -0,0 +1,43 @@
block includes
include ../_util-fns
figure
img(src="/resources/images/devguide/intro/people.png" width="200px" height="152px" alt="Us" align="left" style="margin-left:-40px;margin-right:10px" )
:marked
Everyone learns differently.
You don't have to read the documentation straight through. Most pages stand on their own.
Those new to Angular may wish to follow this popular learning path.
<br class="l-clear-left">
1. [Setup](setup.html "Setup locally withe Quickstart seed") for local Angular development, if you haven't already done so.
1. Take the [*Tour of Heroes* tutorial](../tutorial "Tour of Heroes").
The *Tour of Heroes* takes you step-by-step from [setup](setup.html)
to a full-featured example that demonstrates the essential characteristics of a professional application:
a sensible project structure, data binding, master/detail, services, dependency injection, navigation, and remote data access.
1. <a id="architecture"></a>Read the [Architecture](architecture.html) overview for the big picture.
<li if-docs="ts"><p>
[The Root Module](appmodule.html) introduces the `NgModule` class that tells Angular how to compile and run your application.
</p></li>
1. [Displaying Data](displaying-data.html) shows how data binding puts component property values on screen.
1. [User Input](user-input.html) explains how to respond to user-initiated DOM events.
1. [Forms](forms.html) covers data entry and validation within the UI.
1. [Dependency Injection](dependency-injection.html) is the way to build large, maintainable applications
from small, single-purpose parts.
1. [Template Syntax](template-syntax.html) is a comprehensive study of Angular template HTML.
After reading the above sections, feel free to skip around among the other pages on this site.
.l-sub-section
:marked
### Next Step
Try the [tutorial](../tutorial "Tour of Heroes") if you're ready to start coding or
visit the [Architecture](architecture.html "Basic Concepts") page if you prefer to learn the basic concepts first.

View File

@ -24,6 +24,7 @@ figure
A directive has the same set of lifecycle hooks, minus the hooks that are specific to component content and views.
除了那些组件内容和视图相关的钩子外,指令有相同生命周期钩子。
<br class="l-clear-both">
## Table of Contents
@ -865,7 +866,7 @@ figure.image-display
:marked
### AfterContent hooks
### AfterContent钩子
*AfterContent* hooks are similar to the *AfterView* hooks.
*AfterContent* hooks are similar to the *AfterView* hooks.
The key difference is in the child component
*AfterContent*钩子和*AfterView*相似。关键的不同点是子组件的类型不同。

File diff suppressed because it is too large Load Diff

View File

@ -30,12 +30,12 @@ include ../_util-fns
:marked
We recommend a comprehensive starter-set of packages as specified in the `dependencies` and `devDependencies`
sections of the QuickStart
<a href="https://docs.npmjs.com/files/package.json" target="_blank">package.json</a> file:
sections of the <a href="https://docs.npmjs.com/files/package.json" target="_blank">package.json</a> file
installed as described during [Setup](setup.html).
我们在“快速起步”一章中<a href="https://docs.npmjs.com/files/package.json" target="_blank">package.json</a>文件的
我们在[搭建](setup.html)一章中安装并解释的<a href="https://docs.npmjs.com/files/package.json" target="_blank">package.json</a>文件的
`dependencies`和`devDependencies`区中指定了一组适用于新手的综合依赖包。
+makeJson('quickstart/ts/package.1.json',{ paths: 'dependencies, devDependencies'}, 'package.json (dependencies)')(format=".")
:marked
You can use other packages but we recommend *this particular set* to start with because (a) they work well together and
(b) they include everything you'll need to build and run the sample applications in this series.
@ -243,7 +243,7 @@ a(id="dev-dependencies")
列在`package.json`文件中*devDependencies*区的包会帮助我们开发该应用程序。
我们不用把它们部署到产品环境的应用程序中 —— 虽然这样做也没什么坏处。
***[concurrently](https://www.npmjs.com/package/concurrently)*** -
***[concurrently](https://www.npmjs.com/package/concurrently)*** -
A utility to run multiple *npm* commands concurrently on OS/X, Windows, and Linux operating systems.
***[concurrently](https://www.npmjs.com/package/concurrently)*** - 一个用来在OS/X、Windows和Linux操作系统上同时运行多个*npm*命令的工具

View File

@ -1634,8 +1634,7 @@ a#hero-detail-ctor
provide them for the `id` parameter by name and tell the `HeroService` to fetch the hero with that `id`.
然后,在`ngOnInit`方法中,我们用`ActivatedRoute`服务来接收本路由的参数。
由于这些参数是作为`Observable`可观察对象提供的所以我们_订阅`subscribe`_它们通过名字引用`id`参数,并告诉`HeroService`获取指定`id`的英雄。
我们还要保存这个`Subscription`(订阅的返回值)的引用,供后面做清理工作。
由于这些参数是作为`Observable`可观察对象提供的所以我们用_`switchMap`来通过名字引用`id`参数,并告诉`HeroService`获取指定`id`的英雄。
+makeExcerpt('app/heroes/hero-detail.component.ts (ngOnInit)', 'ngOnInit')

View File

@ -243,7 +243,6 @@ a#HeroListComponent
### The *HeroListComponent* class
### *HeroListComponent*类
Here's the component class:
下面是这个组件类:
@ -371,7 +370,6 @@ a#HeroService
## RxJS library
## RxJS库
[RxJS](https://github.com/ReactiveX/RxJS) ("Reactive Extensions") is a 3rd party library, endorsed by Angular,
that implements the [*asynchronous observable*](https://www.youtube.com/watch?v=UHI0AzD_WfY "Rob Wormald on observables") pattern.
@ -1144,7 +1142,8 @@ a#in-mem-web-api
如果我们只关心获取到的数据我们可以告诉Angular从一个`heroes.json`文件中获取英雄列表,就像这样:
+makeJson('server-communication/ts/app/heroes.json', null, 'app/heroes.json')(format=".")
- var _heroesJsonPath = (_docsFor == 'dart' ? 'web' : 'app') + '/heroes.json';
+makeJson('server-communication/' + _docsFor + '/' + _heroesJsonPath, null, _heroesJsonPath)(format=".")
.l-sub-section
:marked
You wrap the heroes array in an object with a `data` property for the same reason that a data server does:

View File

@ -0,0 +1,154 @@
block includes
include ../_util-fns
:marked
The documentation [setup](setup.html) procedures install a _lot_ of files,
Most of them can be safely ignored.
Application files _inside the_ **`app/`** and **`e2e/`** folders matter most to developers.
Files _outside_ those folders condition the development environment.
They rarely change and you may never view or modify them.
If you do, this page can help you understand their purpose.
style td, th {vertical-align: top}
table(width="100%")
col(width="10%")
col(width="90%")
tr
th File
th Purpose
tr
td <code>app/...</code>
td
:marked
Your Angular application files.
Ships with the "Hello Angular" sample's
`AppComponent`, `AppModule`, a component unit test (`app.component.spec.ts`), and
the bootstrap file, `main.ts`.
tr
td <code>e2e/...</code>
td
:marked
_End-to-end_ (e2e) tests of your application,
written in Jasmine and run by the
<a href="http://www.protractortest.org/" target="_blank" title="Protractor: end-to-end testing for Angular">protractor</a>
e2e test runner.
Initialized with an e2e test for the "Hello Angular" sample.
tr
td <code>node_modules/...</code>
td
:marked
The _npm_ packages installed with the `npm install` command.
tr
td
code.
.editorconfig<br>
.git/...<br>
.gitignore<br>
.travis.yml
td
:marked
Tooling configuration files and folders.
Ignore them until you have a compelling reason to do otherwise.
tr
td <code>CHANGELOG.md</code>
td
:marked
The history of changes to the _QuickStart_ repository.
Delete or ignore.
tr
td <code>favicon.ico</code>
td
:marked
The application icon that appears in the browser tab.
tr
td <code>index.html</code>
td
:marked
The application host page.
It loads a few essential scripts in a prescribed order.
Then it boots the application, placing the root `AppComponent`
in the custom `<my-app>` body tag.
The same `index.html` satisfies all documentation application samples.
tr
td <code>karma.conf.js</code>
td
:marked
Configuration for the <a href="https://karma-runner.github.io/1.0/index.html" target="_blank" title="Karma unit test runner">karma</a>
test runner described in the [Testing](testing.html) guide.
tr
td <code>karma-test-shim.js</code>
td
:marked
Script to run <a href="https://karma-runner.github.io/1.0/index.html" target="_blank" title="Karma unit test runner">karma</a>
with SystemJS as described in the [Testing](testing.html) guide.
tr
td <code>LICENSE</code>
td
:marked
The open source MIT license to use this setup code in your application.
tr
td <code>package.json</code>
td
:marked
Identifies `npm `package dependencies for the project.
Contains command scripts for running the application,
running tests, and more. Enter `npm run` for a listing.
<a href="https://github.com/angular/quickstart/blob/master/README.md#npm-scripts"
target="_blank" title="npm scripts for Angular documentation samples">Read more</a> about them.
tr
td <code>protractor.config.js</code>
td
:marked
Configuration for the
<a href="http://www.protractortest.org/" target="_blank" title="Protractor: end-to-end testing for Angular">protractor</a>
_end-to-end_ (e2e) test runner.
tr
td <code>README.md</code>
td
:marked
Instruction for using this git repository in your project.
Worth reading before deleting.
tr
td <code>styles.css</code>
td
:marked
Global styles for the application. Initialized with an `<h1>` style for the QuickStart demo.
tr
td <code>systemjs<br>.config.js</code>
td
:marked
Tells the **SystemJS** module loader where to find modules
referenced in JavaScript `import` statements such as
code-example(language="ts").
import { Component } from '@angular/core;
:marked
Don't touch this file unless you are fully versed in SystemJS configuration.
tr
td <code>systemjs<br>.config.extras.js</code>
td
:marked
Optional extra SystemJS configuration.
A way to add SystemJS mappings, such as for appliation _barrels_,
without changing the original `system.config.js`.
tr
td <code>tsconfig.json</code>
td
:marked
Tells the TypeScript compiler how to transpile TypeScript source files
into JavaScript files that run in all modern browsers.
tr
td <code>tslint.json</code>
td
:marked
The `npm` installed TypeScript linter inspects your TypeScript code
and complains when you violate one of its rules.
This file defines linting rules favored by the
[Angular style guide](style-guide.html) and by the authors of the documentation.

View File

@ -0,0 +1,180 @@
block includes
include ../_util-fns
- var _prereq = 'node and npm';
- var _playground = 'playground';
- var _Install = 'Install';
//- npm commands
- var _install = 'install';
- var _start = 'start';
a#develop-locally
:marked
## Setup a local development environment
<span if-docs="ts">
The <live-example name=quickstart>QuickStart live-coding</live-example> example is an Angular _playground_.
It's not where you'd develop a real application.
You [should develop locally](#why-locally "Why develop locally") on your own machine ... and that's also how we think you should learn Angular.
</span>
Setting up a new project on your machine is quick and easy with the **QuickStart seed**,
maintained [on github](!{_qsRepo} "Install the github QuickStart repo").
Make sure you have [!{_prereq} installed](#install-prerequisites "What if you don't have !{_prereq}?").
Then ...
1. Create a project folder (you can call it `quickstart` and rename it later).
1. [Clone](#clone "Clone it from github") or [download](#download "download it from github") the **QuickStart seed** into your project folder.
1. !{_Install} [!{_npm}](#install-prerequisites "What if you don't have !{_prereq}?") packages.
1. Run `!{_npm} !{_start}` to launch the sample application.
a#clone
:marked
### Clone
Perform the _clone-to-launch_ steps with these terminal commands.
code-example(language="sh" class="code-shell").
git clone !{_qsRepo}.git quickstart
cd quickstart
!{_npm} !{_install}
!{_npm} !{_start}
a#download
:marked
### Download
<a href="!{_qsRepoZip}" title="Download the QuickStart seed repository">Download the QuickStart seed</a>
and unzip it into your project folder. Then perform the remaining steps with these terminal commands.
code-example(language="sh" class="code-shell").
cd quickstart
!{_npm} !{_install}
!{_npm} !{_start}
.l-main-section#seed
:marked
## What's in the QuickStart seed?
block qs-seed
:marked
The **QuickStart seed** contains the same application as the QuickStart playground
and even has <live-example>its own _playground_</live-example>
that accomodates development of richer examples in a live coding environment.
But it's true purpose is to provide a solid foundation for _local_ development.
Consequently, there are _many more files_ in the project folder on your machine,
most of which you can [learn about later](setup-systemjs-anatomy.html "Setup Anatomy").
block core-files
:marked
Focus on the following three TypeScript (`.ts`) files in the **`/app`** folder.
.filetree
.file app
.children
.file app.component.ts
.file app.module.ts
.file main.ts
+makeTabs(`
setup/ts/app/app.component.ts,
setup/ts/app/app.module.ts,
setup/ts/app/main.ts
`, '', `
app/app.component.ts,
app/app.module.ts,
app/main.ts
`)(format='.')
:marked
All guides and cookbooks have _at least these core files_. Each file has a distinct purpose and evolves independently as the application grows.
style td, th {vertical-align: top}
table(width="100%")
col(width="20%")
col(width="80%")
tr
th File
th Purpose
tr
td <ngio-ex>app.component.ts</ngio-ex>
td
:marked
Defines the same `AppComponent` as the one in the QuickStart !{_playground}.
It is the **root** component of what will become a tree of nested components
as the application evolves.
tr(if-docs="ts")
td <code>app.module.ts</code>
td
:marked
Defines `AppModule`, the [root module](appmodule.html "AppModule: the root module") that tells Angular how to assemble the application.
Right now it declares only the `AppComponent`.
Soon there will be more components to declare.
tr
td <ngio-ex>main.ts</ngio-ex>
td
:marked
Compiles the application with the [JiT compiler](../glossary.html#jit)
and [bootstraps](appmodule.html#main "bootstrap the application") the application to run in the browser.
That's a reasonable choice for the development of most projects and
it's the only viable choice for a sample running in a _live-coding_ environment like Plunker.
You'll learn about alternative compiling and deployment options later in the documentation.
.l-sub-section
:marked
### Next Step
If you're new to Angular, we recommend staying on the [learning path](learning-angular.html).
br
br
a#install-prerequisites
.l-main-section
:marked
## Appendix: !{_prereq}
block install-tooling
:marked
Node.js and npm are essential to modern web development with Angular and other platforms.
Node powers client development and build tools.
The _npm_ package manager, itself a _node_ application, installs JavaScript libraries.
<a href="https://docs.npmjs.com/getting-started/installing-node" target="_blank" title="Installing Node.js and updating npm">
Get them now</a> if they're not already installed on your machine.
**Verify that you are running node `v4.x.x` or higher and npm `3.x.x` or higher**
by running the commands `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors.
We recommend [nvm](https://github.com/creationix/nvm) for managing multiple versions of node and npm.
You may need [nvm](https://github.com/creationix/nvm) if you already have projects running on your machine that
use other versions of node and npm.
+ifDocsFor('ts')
a#why-locally
.l-main-section
:marked
## Appendix: Why develop locally
<live-example>Live coding</live-example> in the browser is a great way to explore Angular.
Links on almost every documentation page open completed samples in the browser.
You can play with the sample code, share your changes with friends, and download and run the code on your own machine.
The [QuickStart](../quickstart.html "Angular QuickStart Playground") shows just the `AppComponent` file.
It creates the equivalent of `app.module.ts` and `main.ts` internally _for the playground only_.
so the reader can discover Angular without distraction.
The other samples are based on the QuickStart seed.
As much fun as this is ...
* you can't ship your app in plunker
* you aren't always online when writing code
* transpiling TypeScript in the browser is slow
* the type support, refactoring, and code completion only work in your local IDE
Use the <live-example><i>live coding</i></live-example> environment as a _playground_,
a place to try the documentation samples and experiment on your own.
It's the perfect place to reproduce a bug when you want to
<a href="https://github.com/angular/angular.io/issues/new" target="_blank" title="File a documentation issue">file a documentation issue</a> or
<a href="https://github.com/angular/angular/issues/new" target="_blank" title="File an Angular issue">file an issue with Angular itself</a>.
For real development, we strongly recommend [developing locally](#develop-locally).

View File

@ -1328,7 +1328,7 @@ a(href="#toc").to-top 回到顶部
准备一个短期和一个长期的实施方案。从零开始,但要时刻考虑应用程序接下来要走的路。
All of the app's code goes in a folder named `app`.
All of the app's code goes in a folder named `app`.
All feature areas are in their own folder, with their own Angular module.
把所有应用程序的源代码都放到名叫`app`的目录里。
@ -1913,8 +1913,8 @@ a(href="#toc").to-top 回到顶部
.file text-filter.component.ts|spec.ts
.file text-filter.service.ts|spec.ts
.file app.component.ts|html|css|spec.ts
.file app.module.ts
.file app-routing.module.ts
.file app.module.ts
.file app-routing.module.ts
.file main.ts
.file index.html
.file ...
@ -2059,8 +2059,8 @@ a(href="#toc").to-top 回到顶部
.file spinner.component.ts|html|css|spec.ts
.file spinner.service.ts|spec.ts
.file app.component.ts|html|css|spec.ts
.file app.module.ts
.file app-routing.module.ts
.file app.module.ts
.file app-routing.module.ts
.file main.ts
.file index.html
.file ...

View File

@ -76,12 +76,13 @@ p.
## HTML
HTML is the language of the Angular template. Our [QuickStart](../quickstart.html) application has a template that is pure HTML:
HTML is the language of the Angular template.
The [QuickStart](../quickstart.html) application has a template that is pure HTML:
HTML是Angular模板的“语言”。我们的[快速起步](../quickstart.html)应用就有一个模板是纯HTML的
HTML是Angular模板的“语言”。我们的[快速起步](../quickstart.html)应用就有一个模板是纯HTML的
code-example(language="html" escape="html").
<h1>My First Angular App</h1>
<h1>Hello Angular</h1>
:marked
Almost all HTML syntax is valid template syntax. The `<script>` element is a notable exception; it is forbidden, eliminating the risk of script injection attacks. (In practice, `<script>` is simply ignored.)
@ -843,8 +844,8 @@ table
[ContentChild](../api/core/index/ContentChild-decorator.html).
如果我们不得不读取目标元素上的属性或调用它的某个方法,我们得用另一种技术。
参见API参考手册中的[viewChild](../api/core/index/ViewChild-var.html)和
[contentChild](../api/core/index/ContentChild-var.html)。
参见API参考手册中的[ViewChild](../api/core/index/ViewChild-var.html)和
[ContentChild](../api/core/index/ContentChild-var.html)。
:marked
### Binding target
@ -994,7 +995,9 @@ a(id="one-time-initialization")
:marked
#### Content security
#### 内容安全
Imagine the following *malicious content*.
假设下面的*恶毒内容*
@ -1006,7 +1009,7 @@ a(id="one-time-initialization")
nor property binding.
幸运的是Angular数据绑定对危险HTML有防备。在显示它们之前它对内容先进行*消毒*。不管是插值表达式还是属性绑定,都**不会**允许带有script标签的HTML泄漏到浏览器中。
+makeExample('template-syntax/ts/app/app.component.html', 'property-binding-vs-interpolation-sanitization')(format=".")
+makeExample('template-syntax/ts/app/app.component.html', 'property-binding-vs-interpolation-sanitization')(format=".")
:marked
Interpolation handles the script tags differently than property binding but both approaches render the
content harmlessly.
@ -1426,7 +1429,6 @@ block style-property-name-dart-diff
Angular为此提供一种特殊的_双向数据绑定_语法:**`[(x)]`**。
`[(x)]`语法结合了_属性绑定_的方括号`[x]`和_事件绑定_的圆括号`(x)`。
.callout.is-important
header [( )] = banana in a box
header [( )] = 盒子里的香蕉
@ -1484,7 +1486,7 @@ block style-property-name-dart-diff
Angular assigns the `$event` value to the `AppComponent.fontSizePx` when the user clicks the buttons.
`$event`变量包含了`SizerComponent.sizeChange`事件的有效荷载。
当用户点击按钮时Angular将`$event`赋值给`AppComponent.fontSize`。
当用户点击按钮时Angular将`$event`赋值给`AppComponent.fontSizePx`。
Clearly the two-way binding syntax is a great convenience compared to separate property and event bindings.
@ -2411,6 +2413,10 @@ h3#aliasing-io 输入/输出属性别名
we expect to bind to an event property that is also called `myClick`.
这是使用[属性(Attribute)型指令](attribute-directives.html)时的常见情况。
指令的使用者期待绑定指令的名字。
例如,当我们在`<div>`标签上使用一个选择器为`myClick`的指令时,
我们期待绑定到一个名字也是`myClick`的事件属性上。
+makeExample('template-syntax/ts/app/app.component.html', 'myClick')(format=".")
:marked
However, the directive name is often a poor choice for the name of a property within the directive class.

View File

@ -382,15 +382,14 @@ table(width="100%")
有两种快速方法立刻开始。
1. Start a new project following the instructions in the
[QuickStart github repository](https://github.com/angular/quickstart/blob/master/README.md).
1. Start a new project following the instructions in [Setup](setup.html).
1. 根据[快速起步的github库](https://github.com/angular/quickstart/blob/master/README.md)中的说明创建新的项目.
根据[搭建](setup.html)中的说明创建新的项目。
1. Start a new project with the
[Angular CLI](https://github.com/angular/angular-cli/blob/master/README.md).
1. 使用[Angular CLI](https://github.com/angular/angular-cli/blob/master/README.md)创建新的项目。
使用[Angular CLI](https://github.com/angular/angular-cli/blob/master/README.md)创建新的项目。
Both approaches install **npm packages, files, and scripts** pre-configured for applications
built in their respective modalities.
@ -399,16 +398,16 @@ table(width="100%")
以上两种方法都安装在各自的模式下为应用预先配置的**npm包、文件和脚本**。它们的文件和规程有一点不同,但是它们的核心部分是一样的,并且在测试代码方面没有任何区别。
In this chapter, the application and its tests are based on the QuickStart repo.
In this chapter, the application and its tests are based on the documentation setup.
在本章中,应用及其测试程序是基于[搭建](setup.html)的。
在本章中,应用及其测试程序是基于《快速起步》库的。
.alert.is-helpful
:marked
If your application was based on the QuickStart repository,
If your application was based on the [Setup](setup.html) instructions,
you can skip the rest of this section and get on with your first test.
The QuickStart repo provides all necessary setup.
如果你的应用是基于《快速起步》库的,可以跳过本小节下面的内容,直接开始第一个测试。
如果你的应用是基于[搭建](setup.html)章所述的,可以跳过本小节下面的内容,直接开始第一个测试。
《快速起步》库一同了所有必须的配置。
#setup-files
@ -463,11 +462,11 @@ table(width="100%")
[SystemJS](https://github.com/systemjs/systemjs/blob/master/README.md)
loads the application and test files.
This script tells SystemJS where to find those files and how to load them.
It's the same version of `systemjs.config.js` used by QuickStart-based applications.
It's the same version of `systemjs.config.js` used by Setup-based applications.
[SystemJS](https://github.com/systemjs/systemjs/blob/master/README.md)
加载应用和测试文件。本脚本告诉SystemJS去哪儿寻找这些文件以及如何加载它们。
`systemjs.config.js`的版本和基于《快速起步》的应用使用的一样。
`systemjs.config.js`的版本和基于[搭建](setup.html)的应用使用的一样。
tr
td(style="vertical-align: top") <code>systemjs.config.extras.js</code>
td
@ -542,7 +541,6 @@ table(width="100%")
### Run karma
### 运行Karma
Compile and run it in karma from the command line with this command:
使用下面的命令从命令行中编译并在`Karma`中运行上面的测试程序。
@ -558,7 +556,7 @@ code-example(format="." language="bash").
.l-sub-section
:marked
The QuickStart development path defined the `test` command in the `scripts` section of npm's `package.json`.
The documentation setup defines the `test` command in the `scripts` section of npm's `package.json`.
The Angular CLI has different commands to do the same thing. Adjust accordingly.
《快速开始》在npm的`package.json`中的`scripts`里定义了`test`命令。
@ -632,7 +630,6 @@ code-example(format="." language="bash").
### Test debugging
### 调试测试程序
Debug specs in the browser in the same way you debug an application.
在浏览器中像调试应用一样调试测试程序spec。
@ -1044,7 +1041,6 @@ a(href="#top").to-top 回到顶部
## Test a component with a dependency
## 测试有依赖的组件
Components often have service dependencies.
The `WelcomeComponent` displays a welcome message to the logged in user.
It knows who the user is based on a property of the injected `UserService`:
@ -1101,7 +1097,6 @@ a(href="#top").to-top 回到顶部
### Get injected services
### 获取注入的服务
The tests need access to the (stub) `UserService` injected into the `WelcomeComponent`.
测试程序需要访问被注入到`WelcomeComponent`中的`UserService`stub类
@ -1218,7 +1213,6 @@ a(href="#top").to-top 回到顶部
## Test a component with an async service
## 测试有异步服务的组件
Many services return values asynchronously.
Most data services make an HTTP request to a remote server and the response is necessarily asynchronous.
@ -1495,7 +1489,6 @@ a(href="#top").to-top 回到顶部
## Test a component with an external template
## 测试有外部模板的组件
The `TestBed.createComponent` is a synchronous method.
It assumes that everything it could need is already in memory.
@ -1587,7 +1580,7 @@ a(href="#top").to-top 回到顶部
nor any of the `override...` methods. The `TestBed` throws an error if you try.
调用`compileComponents`关闭当前的`TestBed`实例,使它不能再被配置。
你不能再调用任何`TestBed`配置方法、`configureTestModule`或者任何`override...`方法,否则`TestBed`将会抛出错误。
你不能再调用任何`TestBed`配置方法、`configureTestingModule`或者任何`override...`方法,否则`TestBed`将会抛出错误。
.alert.is-important
:marked
@ -1611,7 +1604,6 @@ a(href="#top").to-top 回到顶部
## Test a component with inputs and outputs
## 测试带有导入inputs和导出outputs的组件
A component with inputs and outputs typically appears inside the view template of a host component.
The host uses a property binding to set the input property and uses an event binding to
listen to events raised by the output property.
@ -2031,7 +2023,6 @@ a(href="#top").to-top 回到顶部
## Test a routed component with parameters
## 测试带有路由和路由参数的组件
Clicking a _Dashboard_ hero triggers navigation to `heroes/:id` where `:id`
is a route parameter whose value is the `id` of the hero to edit.
That URL matches a route to the `HeroDetailComponent`.
@ -2267,7 +2258,6 @@ a(href="#top").to-top 回到顶部
## Setup with module imports
## 模块导入imports的配置
Earlier component tests configured the testing module with a few `declarations` like this:
此前的组件测试程序使用了一些`declarations`来配置模块,就像这样:
@ -2909,7 +2899,6 @@ a(href="#top").to-top 回到顶部
### Services
### 服务
Services are good candidates for isolated unit testing.
Here are some synchronous and asynchronous unit tests of the `FancyService`
written without assistance from Angular testing utilities.
@ -3000,7 +2989,6 @@ a(href="#top").to-top 回到顶部
### Pipes
### 管道
Pipes are easy to test without the Angular testing utilities.
管道很容易测试无需Angular测试工具。
@ -3031,7 +3019,6 @@ a(href="#top").to-top 回到顶部
#### Write Angular tests too
#### 同时也编写Angular测试
These are tests of the pipe _in isolation_.
They can't tell if the `TitleCasePipe` is working properly as applied in the application components.
@ -3248,7 +3235,6 @@ table
## _TestBed_ Class Summary
## _TestBed_ 类总结
The `TestBed` class is one of the principal Angular testing utilities.
Its API is quite large and can be overwhelming until you've explored it first
a little at a time. Read the early part of this chapter first
@ -3831,7 +3817,7 @@ table
* `By.css(selector)` - 返回符合CSS选择器的元素。
* `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.
* `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.
* `By.directive(directive)` - 返回Angular能匹配一个指令类实例的所有元素。

View File

@ -36,16 +36,16 @@ a(id="tsconfig")
:marked
For details about `tsconfig.json`, see the official
[TypeScript wiki](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html).
要了解关于`tsconfig.json`的详情,请参阅官方提供的
[TypeScript wiki](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html)。
:marked
We created the following `tsconfig.json` for [QuickStart](../quickstart.html):
We created the following `tsconfig.json` during [Setup](setup.html):
我们在[快速起步](../quickstart.html)中创建过如下的`tsconfig.json`
我们在[搭建](setup.html)中创建过如下的`tsconfig.json`
+makeJson('quickstart/ts/tsconfig.1.json', null, 'tsconfig.json')(format=".")
+makeJson('quickstart/ts/tsconfig.json', null, 'tsconfig.json')(format=".")
:marked
This file contains options and flags that are essential for Angular applications.
@ -64,15 +64,15 @@ a(id="tsconfig")
但是我们的选择会在大项目中产生显著差异,所以它值得讨论一番。
When the `noImplicitAny` flag is `false` (the default), and if
the compiler cannot infer the variable type based on how it's used, the compiler silently defaults the type to `any`. That's what is meant by *implicit `any`*.
the compiler cannot infer the variable type based on how it's used,
the compiler silently defaults the type to `any`. That's what is meant by *implicit `any`*.
当`noImplicitAny`标志是`false`(默认值)时,
如果编译器无法根据变量的用途推断出变量的类型,它就会悄悄的把变量类型默认为`any`。这就是*隐式`any`*的含义。
In the QuickStart exercise, the `noImplicitAny` flag is initialized to `false`
to make learning TypeScript development easier.
The documentation setup sets the `noImplicitAny` flag to `true`.
我们在“快速起步”中把`noImplicitAny`标志初始化为`false`这是为了让学习TypeScript开发更简单点
[搭建](setup.html)文档将`noImplicitAny`标志设置为`true`
When the `noImplicitAny` flag is `true` and the TypeScript compiler cannot infer
the type, it still generates the JavaScript files, but it also **reports an error**.
@ -84,10 +84,10 @@ a(id="tsconfig")
很多饱经沧桑的程序员更喜欢这种严格的设置,因为类型检查能在编译期间捕获更多意外错误。
You can set a variable's type to `any` even when the `noImplicitAny` flag is `true`.
即使`noImplicitAny`标志被设置成了`true`,你也可以把变量的类型设置为`any`。
If you set the `noImplicitAny` flag to `true`, you may get *implicit index errors* as well.
When the `noImplicitAny` flag is `true, you may get *implicit index errors* as well.
Most developers feel that *this particular error* is more annoying than helpful.
You can suppress them with the following additional flag:
@ -98,6 +98,8 @@ a(id="tsconfig")
code-example(format=".").
"suppressImplicitAnyIndexErrors":true
:marked
The documentation setup sets this flag to `true` as well.
a(id="typings")
.l-main-section
@ -129,10 +131,32 @@ a(id="typings")
很多库在自己的npm包中都包含了它们的类型定义文件TypeScript编译器和编辑器都能找到它们。Angular库也是这样的。
任何Angular应用程序的`node_modules/@angular/core/`目录下,都包含几个`d.ts`文件它们描述了Angular的各个部分。
**You need do nothing to get *typings* files for library packages that include `d.ts` files &mdash; as all Angular packages do.**
**You need do nothing to get *typings* files for library packages that include `d.ts` files&mdash;as all Angular packages do.**
**我们不需要为那些包含了`d.ts`文件的库获取*类型定义*文件 —— Angular的所有包都是如此。**
### lib.d.ts
### lib.d.ts
TypeScript includes a special declaration file called `lib.d.ts`. This file contains the ambient declarations for various common JavaScript constructs present in JavaScript runtimes and the DOM.
TypeScript带有一个特殊的声明文件名为`lib.d.ts`。该文件包含了JavaScript运行库和DOM的各种常用JavaScript环境声明。
Based on the `--target`, TypeScript adds _additional_ ambient declarations like `Promise` if our target is `es6`.
基于`--target`TypeScript添加*额外*的环境声明,例如如果目标为`es6`时将添加`Promise`。
Since the QuickStart is targeting `es5`, we can override the list of declaration files to be included:
因为《快速开始》的目标为`es5`,所以我们可以重写声明文件列表来包含:
code-example(format=".")
"lib": ["es2015", "dom"]
:marked
Thanks to that, we have all the `es6` typings even when targeting `es5`.
### Installable typings files
### 安装类型定义文件
Many libraries&mdash;jQuery, Jasmine, and Lodash among them&mdash;do *not* include `d.ts` files in their npm packages.
@ -142,20 +166,15 @@ a(id="typings")
遗憾的是,很多库 —— jQuery、Jasmine和Lodash等库 —— 都*没有*在它们自己的npm包中包含`d.ts`文件。
幸运的是,它们的作者或社区中的贡献者已经为这些库创建了独立的`d.ts`文件,并且把它们发布到了一个众所周知的位置。
We can install these typings via `npm` using the
We can install these typings via `npm` using the
[`@types/*` scoped package](http://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html)
and Typescript (starting at 2.0) will automatically recognize them.
For instance, to install typings for `jasmine` we could do `npm install @types/jasmine --save-dev`.
:marked
QuickStart identified three *typings* (`d.ts`) files:
QuickStart identified two *typings* (`d.ts`) files:
我们在“快速起步”中指定过三个*类型定义*文件(`d.ts`
* [core-js](https://github.com/zloirock/core-js/blob/master/README.md)
brings ES2015/ES6 capabilities to ES5 browsers
* [core-js](https://github.com/zloirock/core-js/blob/master/README.md)是为ES5浏览器添加ES2015/ES6特性的类型定义
我们在“快速起步”中指定过两个*类型定义*文件(`d.ts`
* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework
@ -170,4 +189,4 @@ a(id="typings")
QuickStart doesn't require these typings but many of the samples do.
“快速起步”本身不需要这些类型定义,但是文档中的很多例子都需要。

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