diff --git a/gulpfile.js b/gulpfile.js index 6fd9eb355e..0d137ded2e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -295,14 +295,16 @@ function runE2eTsTests(appDir, outputFile) { try { var exampleConfig = fs.readJsonSync(`${appDir}/${_exampleConfigFilename}`); } catch (e) { - exampleConfig = { - build: 'tsc', - run: 'http-server:e2e' - }; + exampleConfig = {}; } - var appBuildSpawnInfo = spawnExt('npm', ['run', exampleConfig.build], { cwd: appDir }); - var appRunSpawnInfo = spawnExt('npm', ['run', exampleConfig.run, '--', '-s'], { cwd: appDir }); + var config = { + build: exampleConfig.build || 'tsc', + run: exampleConfig.run || 'http-server:e2e' + }; + + var appBuildSpawnInfo = spawnExt('npm', ['run', config.build], { cwd: appDir }); + var appRunSpawnInfo = spawnExt('npm', ['run', config.run, '--', '-s'], { cwd: appDir }); return runProtractor(appBuildSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile); } @@ -1265,7 +1267,7 @@ function apiExamplesWatch(postShredAction) { } function devGuideExamplesWatch(shredOptions, postShredAction, focus) { - var watchPattern = focus ? '**/' + focus + '/**/*.*' : '**/*.*'; + var watchPattern = focus ? '**/{' + focus + ',cb-' + focus+ '}/**/*.*' : '**/*.*'; var includePattern = path.join(shredOptions.examplesDir, watchPattern); // removed this version because gulp.watch has the same glob issue that dgeni has. // var excludePattern = '!' + path.join(shredOptions.examplesDir, '**/node_modules/**/*.*'); diff --git a/public/docs/_examples/architecture/dart/pubspec.yaml b/public/docs/_examples/architecture/dart/pubspec.yaml index e2e648537b..3f869b06ca 100644 --- a/public/docs/_examples/architecture/dart/pubspec.yaml +++ b/public/docs/_examples/architecture/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: developer_guide_intro description: Developer Guide Intro version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/attribute-directives/dart/pubspec.yaml b/public/docs/_examples/attribute-directives/dart/pubspec.yaml index 79904bff12..7b14c2b11c 100644 --- a/public/docs/_examples/attribute-directives/dart/pubspec.yaml +++ b/public/docs/_examples/attribute-directives/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: attribute_directives description: Attribute directives example version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/cb-i18n/e2e-spec.ts b/public/docs/_examples/cb-i18n/e2e-spec.ts new file mode 100644 index 0000000000..6606ca8878 --- /dev/null +++ b/public/docs/_examples/cb-i18n/e2e-spec.ts @@ -0,0 +1,13 @@ +/// +'use strict'; +describe('i18n E2E Tests', () => { + + beforeEach(function () { + browser.get(''); + }); + + it('should display i18n translated welcome: Bonjour i18n!', function () { + expect(element(by.css('h1')).getText()).toEqual('Bonjour i18n!'); + }); + +}); diff --git a/public/docs/_examples/cb-i18n/ts/.gitignore b/public/docs/_examples/cb-i18n/ts/.gitignore new file mode 100644 index 0000000000..8357331dc7 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/.gitignore @@ -0,0 +1,6 @@ +**/*.ngfactory.ts +**/*.metadata.json +**/messages.xlf +dist +!app/tsconfig.json +!rollup.js \ No newline at end of file diff --git a/public/docs/_examples/cb-i18n/ts/app/app.component.1.html b/public/docs/_examples/cb-i18n/ts/app/app.component.1.html new file mode 100644 index 0000000000..7813de7d31 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/app/app.component.1.html @@ -0,0 +1,11 @@ + +

Hello i18n!

+ + + +

Hello i18n!

+ + + +

Hello i18n!

+ diff --git a/public/docs/_examples/cb-i18n/ts/app/app.component.html b/public/docs/_examples/cb-i18n/ts/app/app.component.html new file mode 100644 index 0000000000..3469b42e86 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/app/app.component.html @@ -0,0 +1,4 @@ + + +

Hello i18n!

+ \ No newline at end of file diff --git a/public/docs/_examples/cb-i18n/ts/app/app.component.ts b/public/docs/_examples/cb-i18n/ts/app/app.component.ts new file mode 100644 index 0000000000..e065c38917 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/app/app.component.ts @@ -0,0 +1,10 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'my-app', + templateUrl: 'app.component.html' +}) +export class AppComponent { } + diff --git a/public/docs/_examples/cb-i18n/ts/app/app.module.ts b/public/docs/_examples/cb-i18n/ts/app/app.module.ts new file mode 100644 index 0000000000..64ad44075b --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/app/app.module.ts @@ -0,0 +1,13 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) + +export class AppModule { } diff --git a/public/docs/_examples/cb-i18n/ts/app/i18n-providers.ts b/public/docs/_examples/cb-i18n/ts/app/i18n-providers.ts new file mode 100644 index 0000000000..c27afc88d7 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/app/i18n-providers.ts @@ -0,0 +1,33 @@ +// #docregion +import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from '@angular/core'; + +export function getTranslationProviders(): Promise { + + // Get the locale id from the global + const locale = document['locale'] as string; + + // return no providers if fail to get translation file for locale + const noProviders: Object[] = []; + + // No locale or English: no translation providers + if (!locale || locale === 'en') { + return Promise.resolve(noProviders); + } + + // Ex: 'i18n/fr/messages.fr.xlf` + const translationFile = `./i18n/${locale}/messages.${locale}.xlf`; + + return getTranslationsWithSystemJs(translationFile) + .then( (translations: string ) => [ + { provide: TRANSLATIONS, useValue: translations }, + { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }, + { provide: LOCALE_ID, useValue: locale } + ]) + .catch(() => noProviders); // ignore if file not found +} + +declare var System: any; + +function getTranslationsWithSystemJs(file: string) { + return System.import(file + '!text'); // relies on text plugin +} diff --git a/public/docs/_examples/cb-i18n/ts/app/main.1.ts b/public/docs/_examples/cb-i18n/ts/app/main.1.ts new file mode 100644 index 0000000000..961a226688 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/app/main.1.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-i18n/ts/app/main.ts b/public/docs/_examples/cb-i18n/ts/app/main.ts new file mode 100644 index 0000000000..79d5fa0b48 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/app/main.ts @@ -0,0 +1,10 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { getTranslationProviders } from './i18n-providers'; + +import { AppModule } from './app.module'; + +getTranslationProviders().then(providers => { + const options = { providers }; + platformBrowserDynamic().bootstrapModule(AppModule, options); +}); diff --git a/public/docs/_examples/cb-i18n/ts/example-config.json b/public/docs/_examples/cb-i18n/ts/example-config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/cb-i18n/ts/i18n/fr/messages.fr.xlf b/public/docs/_examples/cb-i18n/ts/i18n/fr/messages.fr.xlf new file mode 100644 index 0000000000..005b98ba73 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/i18n/fr/messages.fr.xlf @@ -0,0 +1,13 @@ + + + + + + Hello i18n! + Bonjour i18n! + An introduction header for this sample + User welcome + + + + diff --git a/public/docs/_examples/cb-i18n/ts/i18n/fr/messages.fr.xlf.html b/public/docs/_examples/cb-i18n/ts/i18n/fr/messages.fr.xlf.html new file mode 100644 index 0000000000..2130c25275 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/i18n/fr/messages.fr.xlf.html @@ -0,0 +1,17 @@ + + + + + + + + + Hello i18n! + Bonjour i18n! + An introduction header for this sample + User welcome + + + + + diff --git a/public/docs/_examples/cb-i18n/ts/i18n/trans-unit.html b/public/docs/_examples/cb-i18n/ts/i18n/trans-unit.html new file mode 100644 index 0000000000..6cb66ca12d --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/i18n/trans-unit.html @@ -0,0 +1,7 @@ + + + Hello i18n! + + An introduction header for this sample + User welcome + diff --git a/public/docs/_examples/cb-i18n/ts/index.html b/public/docs/_examples/cb-i18n/ts/index.html new file mode 100644 index 0000000000..fc88d9284e --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/index.html @@ -0,0 +1,39 @@ + + + + + Angular i18n example + + + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/cb-i18n/ts/plnkr.json b/public/docs/_examples/cb-i18n/ts/plnkr.json new file mode 100644 index 0000000000..aa6421b303 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/plnkr.json @@ -0,0 +1,17 @@ +{ + "description": "i18n", + "files": [ + "app/**/*.css", + "app/**/*.html", + "app/**/*.ts", + "i18n/messages.xlf", + "i18n/fr/messages.fr.xlf", + + "!**/*.[1].*", + + "styles.css", + "systemjs-text-plugin.js", + "index.html" + ], + "tags": ["i18n"] +} diff --git a/public/docs/_examples/cb-i18n/ts/systemjs-text-plugin.js b/public/docs/_examples/cb-i18n/ts/systemjs-text-plugin.js new file mode 100644 index 0000000000..d5ca508fe0 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/systemjs-text-plugin.js @@ -0,0 +1,14 @@ +// #docregion +/* + SystemJS Text plugin from + https://github.com/systemjs/plugin-text/blob/master/text.js +*/ +exports.translate = function(load) { + if (this.builder && this.transpiler) { + load.metadata.format = 'esm'; + return 'exp' + 'ort var __useDefault = true; exp' + 'ort default ' + JSON.stringify(load.source) + ';'; + } + + load.metadata.format = 'amd'; + return 'def' + 'ine(function() {\nreturn ' + JSON.stringify(load.source) + ';\n});'; +} diff --git a/public/docs/_examples/component-styles/dart/pubspec.yaml b/public/docs/_examples/component-styles/dart/pubspec.yaml index 7521cf8365..b937fd8f72 100755 --- a/public/docs/_examples/component-styles/dart/pubspec.yaml +++ b/public/docs/_examples/component-styles/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: component_styles description: Component Styles example version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/dependency-injection/dart/pubspec.yaml b/public/docs/_examples/dependency-injection/dart/pubspec.yaml index b5958b1e07..366b014304 100644 --- a/public/docs/_examples/dependency-injection/dart/pubspec.yaml +++ b/public/docs/_examples/dependency-injection/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: dependency_injection description: Dependency injection sample version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/displaying-data/dart/pubspec.yaml b/public/docs/_examples/displaying-data/dart/pubspec.yaml index 2c5961c70e..ad1736d951 100644 --- a/public/docs/_examples/displaying-data/dart/pubspec.yaml +++ b/public/docs/_examples/displaying-data/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: displaying_data description: Displaying Data version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/forms/dart/pubspec.yaml b/public/docs/_examples/forms/dart/pubspec.yaml index 43a19366d7..4f13a2ca4b 100644 --- a/public/docs/_examples/forms/dart/pubspec.yaml +++ b/public/docs/_examples/forms/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: hero_form description: Form example version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml b/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml index d18bc10490..d7a003cf3c 100644 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml +++ b/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: 'hierarchical_di' description: Hierarchical dependency injection example version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml b/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml index e1bda01d28..25c5106c9b 100644 --- a/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml +++ b/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: lifecycle_hooks description: Lifecycle Hooks version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/package.json b/public/docs/_examples/package.json index 93fbd36f17..980813eabd 100644 --- a/public/docs/_examples/package.json +++ b/public/docs/_examples/package.json @@ -20,41 +20,43 @@ "test:webpack": "karma start karma.webpack.conf.js", "build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail", "build:cli": "ng build", - "build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup.js" + "build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup.js", + "i18n": "ng-xi18n" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { - "@angular/common": "2.0.0", - "@angular/compiler": "2.0.0", - "@angular/compiler-cli": "0.6.2", - "@angular/core": "2.0.0", - "@angular/forms": "2.0.0", - "@angular/http": "2.0.0", - "@angular/platform-browser": "2.0.0", - "@angular/platform-browser-dynamic": "2.0.0", - "@angular/platform-server": "2.0.0", - "@angular/router": "3.0.0", - "@angular/upgrade": "2.0.0", - "angular-in-memory-web-api": "~0.1.0", - "bootstrap": "^3.3.6", + "@angular/common": "~2.0.1", + "@angular/compiler": "~2.0.1", + "@angular/compiler-cli": "~0.6.3", + "@angular/core": "~2.0.1", + "@angular/forms": "~2.0.1", + "@angular/http": "~2.0.1", + "@angular/platform-browser": "~2.0.1", + "@angular/platform-browser-dynamic": "~2.0.1", + "@angular/platform-server": "~2.0.1", + "@angular/router": "~3.0.1", + "@angular/upgrade": "~2.0.1", + + "angular-in-memory-web-api": "~0.1.1", + "bootstrap": "^3.3.7", "core-js": "^2.4.1", - "reflect-metadata": "^0.1.3", - "rollup": "^0.34.13", + "reflect-metadata": "^0.1.8", + "rollup": "^0.36.0", "rollup-plugin-node-resolve": "^2.0.0", "rollup-plugin-uglify": "^1.0.1", "rxjs": "5.0.0-beta.12", - "systemjs": "0.19.38", - "zone.js": "^0.6.23" + "systemjs": "0.19.39", + "zone.js": "^0.6.25" }, "devDependencies": { "angular-cli": "^1.0.0-beta.5", "angular2-template-loader": "^0.4.0", "awesome-typescript-loader": "^2.2.4", "canonical-path": "0.0.2", - "concurrently": "^2.2.0", - "css-loader": "^0.23.1", + "concurrently": "^3.0.0", + "css-loader": "^0.25.0", "extract-text-webpack-plugin": "^1.0.1", "file-loader": "^0.8.5", "html-loader": "^0.4.3", @@ -71,19 +73,19 @@ "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^1.8.0", "lite-server": "^2.2.2", - "lodash": "^4.13.1", + "lodash": "^4.16.2", "null-loader": "^0.1.1", "phantomjs-prebuilt": "^2.1.7", "protractor": "^3.3.0", "raw-loader": "^0.5.1", - "rimraf": "^2.5.2", + "rimraf": "^2.5.4", "rollup-plugin-commonjs": "^4.1.0", "style-loader": "^0.13.1", "ts-loader": "^0.8.2", "ts-node": "^1.3.0", "tslint": "^3.15.1", - "typescript": "^2.0.2", - "typings": "^1.3.2", + "typescript": "^2.0.3", + "typings": "^1.4.0", "webpack": "^1.13.0", "webpack-dev-server": "^1.14.1", "webpack-merge": "^0.14.0" diff --git a/public/docs/_examples/pipes/dart/pubspec.yaml b/public/docs/_examples/pipes/dart/pubspec.yaml index e48db77d96..6ac1328d66 100644 --- a/public/docs/_examples/pipes/dart/pubspec.yaml +++ b/public/docs/_examples/pipes/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: pipe_examples description: Pipes Example version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/quickstart/dart/lib/app_component.dart b/public/docs/_examples/quickstart/dart/lib/app_component.dart index 6e089a6303..b300a28992 100644 --- a/public/docs/_examples/quickstart/dart/lib/app_component.dart +++ b/public/docs/_examples/quickstart/dart/lib/app_component.dart @@ -5,7 +5,7 @@ import 'package:angular2/core.dart'; // #docregion metadata @Component( selector: 'my-app', - template: '

My First Angular 2 App

') + template: '

My First Angular App

') // #enddocregion metadata // #docregion class class AppComponent {} diff --git a/public/docs/_examples/quickstart/dart/pubspec.yaml b/public/docs/_examples/quickstart/dart/pubspec.yaml index b8ad984d4c..39b7e10d28 100644 --- a/public/docs/_examples/quickstart/dart/pubspec.yaml +++ b/public/docs/_examples/quickstart/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: angular2_quickstart description: QuickStart version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/quickstart/ts/package.1.json b/public/docs/_examples/quickstart/ts/package.1.json index 751f1e3f0b..ea5d056bf4 100644 --- a/public/docs/_examples/quickstart/ts/package.1.json +++ b/public/docs/_examples/quickstart/ts/package.1.json @@ -2,7 +2,7 @@ "name": "angular-quickstart", "version": "1.0.0", "scripts": { - "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ", + "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ", "lite": "lite-server", "postinstall": "typings install", "tsc": "tsc", @@ -11,29 +11,28 @@ }, "license": "ISC", "dependencies": { - "@angular/common": "2.0.0", - "@angular/compiler": "2.0.0", - "@angular/core": "2.0.0", - "@angular/forms": "2.0.0", - "@angular/http": "2.0.0", - "@angular/platform-browser": "2.0.0", - "@angular/platform-browser-dynamic": "2.0.0", - "@angular/router": "3.0.0", - "@angular/upgrade": "2.0.0", + "@angular/common": "~2.0.1", + "@angular/compiler": "~2.0.1", + "@angular/core": "~2.0.1", + "@angular/forms": "~2.0.1", + "@angular/http": "~2.0.1", + "@angular/platform-browser": "~2.0.1", + "@angular/platform-browser-dynamic": "~2.0.1", + "@angular/router": "~3.0.1", + "@angular/upgrade": "~2.0.1", + "angular-in-memory-web-api": "~0.1.1", + "bootstrap": "^3.3.7", "core-js": "^2.4.1", - "reflect-metadata": "^0.1.3", + "reflect-metadata": "^0.1.8", "rxjs": "5.0.0-beta.12", - "systemjs": "0.19.27", - "zone.js": "^0.6.23", - - "angular-in-memory-web-api": "0.1.3", - "bootstrap": "^3.3.6" + "systemjs": "0.19.39", + "zone.js": "^0.6.25" }, "devDependencies": { - "concurrently": "^2.2.0", + "concurrently": "^3.0.0", "lite-server": "^2.2.2", - "typescript": "^2.0.2", - "typings":"^1.3.2" + "typescript": "^2.0.3", + "typings":"^1.4.0" } } diff --git a/public/docs/_examples/server-communication/dart/pubspec.yaml b/public/docs/_examples/server-communication/dart/pubspec.yaml index a2a1b30e93..aaf85be4d2 100644 --- a/public/docs/_examples/server-communication/dart/pubspec.yaml +++ b/public/docs/_examples/server-communication/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: server_communication description: Server Communication version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 http: ^0.11.3+3 diff --git a/public/docs/_examples/server-communication/dart/web/index.html b/public/docs/_examples/server-communication/dart/web/index.html index fc365968c2..529e5d1c9c 100644 --- a/public/docs/_examples/server-communication/dart/web/index.html +++ b/public/docs/_examples/server-communication/dart/web/index.html @@ -2,7 +2,7 @@ - Angular 2 Http Demo + Angular Http Demo diff --git a/public/docs/_examples/structural-directives/dart/pubspec.yaml b/public/docs/_examples/structural-directives/dart/pubspec.yaml index c4c0bca74a..46542a7424 100644 --- a/public/docs/_examples/structural-directives/dart/pubspec.yaml +++ b/public/docs/_examples/structural-directives/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: structural_directives description: Structural directives example version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/structural-directives/dart/web/index.html b/public/docs/_examples/structural-directives/dart/web/index.html index 38da87dc69..7d5b4d15c9 100644 --- a/public/docs/_examples/structural-directives/dart/web/index.html +++ b/public/docs/_examples/structural-directives/dart/web/index.html @@ -3,7 +3,7 @@ - Angular 2 Structural Directives + Angular Structural Directives diff --git a/public/docs/_examples/style-guide/e2e-spec.ts b/public/docs/_examples/style-guide/e2e-spec.ts index 8066df6e7b..2809e65e44 100644 --- a/public/docs/_examples/style-guide/e2e-spec.ts +++ b/public/docs/_examples/style-guide/e2e-spec.ts @@ -77,13 +77,6 @@ describe('Style Guide', function () { expect(div.getText()).toBe('This is heroes component'); }); - it('04-14', function () { - browser.get('#/04-14'); - - let h2 = element(by.tagName('sg-app > toh-heroes > div > h2')); - expect(h2.getText()).toBe('My Heroes'); - }); - it('05-02', function () { browser.get('#/05-02'); diff --git a/public/docs/_examples/style-guide/ts/02-05/app/app.component.ts b/public/docs/_examples/style-guide/ts/02-05/app/app.component.ts new file mode 100644 index 0000000000..268a2f940b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/02-05/app/app.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'toh-app', + template: ` + Tour of Heroes + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/04-14/app/app.module.ts b/public/docs/_examples/style-guide/ts/02-05/app/app.module.ts similarity index 52% rename from public/docs/_examples/style-guide/ts/04-14/app/app.module.ts rename to public/docs/_examples/style-guide/ts/02-05/app/app.module.ts index a9377ce9d6..306ec125e0 100644 --- a/public/docs/_examples/style-guide/ts/04-14/app/app.module.ts +++ b/public/docs/_examples/style-guide/ts/02-05/app/app.module.ts @@ -1,19 +1,23 @@ +// #docplaster +// #docregion import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; -import { HeroesComponent } from './heroes'; @NgModule({ imports: [ BrowserModule, - RouterModule.forChild([{ path: '04-14', component: AppComponent }]) + // #enddocregion + RouterModule.forChild([{ path: '02-05', component: AppComponent }]) + // #docregion ], declarations: [ - AppComponent, - HeroesComponent + AppComponent ], - exports: [ AppComponent ] + exports: [ AppComponent ], + bootstrap: [ AppComponent ] }) -export class AppModule {} +export class AppModule { } +// #enddocregion diff --git a/public/docs/_examples/style-guide/ts/02-05/main.ts b/public/docs/_examples/style-guide/ts/02-05/main.ts new file mode 100644 index 0000000000..6c32161f84 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/02-05/main.ts @@ -0,0 +1,8 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule) + .then(success => console.log(`Bootstrap success`)) + .catch(err => console.error(err)); diff --git a/public/docs/_examples/style-guide/ts/02-08/app/app.module.ts b/public/docs/_examples/style-guide/ts/02-08/app/app.module.ts index a86c713d4f..e840cc50a5 100644 --- a/public/docs/_examples/style-guide/ts/02-08/app/app.module.ts +++ b/public/docs/_examples/style-guide/ts/02-08/app/app.module.ts @@ -2,7 +2,8 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; -import { ValidateDirective } from './shared'; +import { InputHighlightDirective, + ValidateDirective } from './shared'; @NgModule({ imports: [ @@ -10,6 +11,7 @@ import { ValidateDirective } from './shared'; ], declarations: [ AppComponent, + InputHighlightDirective, ValidateDirective ], exports: [ AppComponent ] diff --git a/public/docs/_examples/style-guide/ts/02-08/app/shared/index.ts b/public/docs/_examples/style-guide/ts/02-08/app/shared/index.ts index 2534dc7b6d..b844b75492 100644 --- a/public/docs/_examples/style-guide/ts/02-08/app/shared/index.ts +++ b/public/docs/_examples/style-guide/ts/02-08/app/shared/index.ts @@ -1 +1,2 @@ +export * from './input-highlight.directive'; export * from './validate.directive'; diff --git a/public/docs/_examples/style-guide/ts/02-08/app/shared/input-highlight.directive.ts b/public/docs/_examples/style-guide/ts/02-08/app/shared/input-highlight.directive.ts new file mode 100644 index 0000000000..e9033a9627 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/02-08/app/shared/input-highlight.directive.ts @@ -0,0 +1,10 @@ +// #docregion +import { Directive, ElementRef, Renderer } from '@angular/core'; + +@Directive({ selector: 'input'}) +/** Highlight the attached input text element in blue */ +export class InputHighlightDirective { + constructor(renderer: Renderer, el: ElementRef) { + renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'powderblue'); + } +} diff --git a/public/docs/_examples/style-guide/ts/03-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-01/app/app.component.ts index 20bedca7d5..cb9479d2d9 100644 --- a/public/docs/_examples/style-guide/ts/03-01/app/app.component.ts +++ b/public/docs/_examples/style-guide/ts/03-01/app/app.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit } from '@angular/core'; -import { ExceptionService } from './shared'; +import { ExceptionService } from './core'; @Component({ selector: 'sg-app', diff --git a/public/docs/_examples/style-guide/ts/03-01/app/shared/exception.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-01/app/core/exception.service.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-01/app/shared/exception.service.avoid.ts rename to public/docs/_examples/style-guide/ts/03-01/app/core/exception.service.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/03-01/app/shared/exception.service.ts b/public/docs/_examples/style-guide/ts/03-01/app/core/exception.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-01/app/shared/exception.service.ts rename to public/docs/_examples/style-guide/ts/03-01/app/core/exception.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-01/app/shared/index.ts b/public/docs/_examples/style-guide/ts/03-01/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-01/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/03-01/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-01/app/index.ts b/public/docs/_examples/style-guide/ts/03-01/app/index.ts index ebe5c92f03..e120e2dbfd 100644 --- a/public/docs/_examples/style-guide/ts/03-01/app/index.ts +++ b/public/docs/_examples/style-guide/ts/03-01/app/index.ts @@ -1,2 +1,2 @@ -export * from './shared'; +export * from './core'; export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/03-02/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-02/app/app.component.ts index cb62984849..132ea54c85 100644 --- a/public/docs/_examples/style-guide/ts/03-02/app/app.component.ts +++ b/public/docs/_examples/style-guide/ts/03-02/app/app.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; -import { heroesUrl, mockHeroes, VILLAINS_URL } from './shared'; +import { heroesUrl, mockHeroes, VILLAINS_URL } from './core'; @Component({ selector: 'sg-app', diff --git a/public/docs/_examples/style-guide/ts/03-02/app/shared/data.service.ts b/public/docs/_examples/style-guide/ts/03-02/app/core/data.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-02/app/shared/data.service.ts rename to public/docs/_examples/style-guide/ts/03-02/app/core/data.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-02/app/shared/index.ts b/public/docs/_examples/style-guide/ts/03-02/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-02/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/03-02/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-02/app/index.ts b/public/docs/_examples/style-guide/ts/03-02/app/index.ts index ebe5c92f03..e120e2dbfd 100644 --- a/public/docs/_examples/style-guide/ts/03-02/app/index.ts +++ b/public/docs/_examples/style-guide/ts/03-02/app/index.ts @@ -1,2 +1,2 @@ -export * from './shared'; +export * from './core'; export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/03-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-03/app/app.component.ts index 2bab2c3c47..3ca522bc45 100644 --- a/public/docs/_examples/style-guide/ts/03-03/app/app.component.ts +++ b/public/docs/_examples/style-guide/ts/03-03/app/app.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit } from '@angular/core'; -import { Hero, HeroCollectorService } from './shared'; +import { Hero, HeroCollectorService } from './core'; @Component({ selector: 'sg-app', diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/hero-collector.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-03/app/core/hero-collector.service.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/hero-collector.service.avoid.ts rename to public/docs/_examples/style-guide/ts/03-03/app/core/hero-collector.service.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/hero-collector.service.ts b/public/docs/_examples/style-guide/ts/03-03/app/core/hero-collector.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/hero-collector.service.ts rename to public/docs/_examples/style-guide/ts/03-03/app/core/hero-collector.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/hero.model.avoid.ts b/public/docs/_examples/style-guide/ts/03-03/app/core/hero.model.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/hero.model.avoid.ts rename to public/docs/_examples/style-guide/ts/03-03/app/core/hero.model.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/03-03/app/core/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/03-03/app/core/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/index.ts b/public/docs/_examples/style-guide/ts/03-03/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/03-03/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/index.ts b/public/docs/_examples/style-guide/ts/03-03/app/index.ts index ebe5c92f03..e120e2dbfd 100644 --- a/public/docs/_examples/style-guide/ts/03-03/app/index.ts +++ b/public/docs/_examples/style-guide/ts/03-03/app/index.ts @@ -1,2 +1,2 @@ -export * from './shared'; +export * from './core'; export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/03-04/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-04/app/app.component.ts index d7da5134bc..555c9e9441 100644 --- a/public/docs/_examples/style-guide/ts/03-04/app/app.component.ts +++ b/public/docs/_examples/style-guide/ts/03-04/app/app.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit } from '@angular/core'; -import { ToastService } from './shared'; +import { ToastService } from './core'; @Component({ selector: 'sg-app', diff --git a/public/docs/_examples/style-guide/ts/03-04/app/shared/index.ts b/public/docs/_examples/style-guide/ts/03-04/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-04/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/03-04/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-04/app/core/toast.service.avoid.ts similarity index 65% rename from public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.avoid.ts rename to public/docs/_examples/style-guide/ts/03-04/app/core/toast.service.avoid.ts index 0f3a7c25ea..e2e21b8e4c 100644 --- a/public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.avoid.ts +++ b/public/docs/_examples/style-guide/ts/03-04/app/core/toast.service.avoid.ts @@ -8,19 +8,19 @@ import { Injectable } from '@angular/core'; export class ToastService { message: string; - private _toastCount: number; + private toastCount: number; hide() { - this._toastCount--; - this._log(); + this.toastCount--; + this.log(); } show() { - this._toastCount++; - this._log(); + this.toastCount++; + this.log(); } - private _log() { + private log() { console.log(this.message); } } diff --git a/public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.ts b/public/docs/_examples/style-guide/ts/03-04/app/core/toast.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.ts rename to public/docs/_examples/style-guide/ts/03-04/app/core/toast.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-04/app/index.ts b/public/docs/_examples/style-guide/ts/03-04/app/index.ts index ebe5c92f03..e120e2dbfd 100644 --- a/public/docs/_examples/style-guide/ts/03-04/app/index.ts +++ b/public/docs/_examples/style-guide/ts/03-04/app/index.ts @@ -1,2 +1,2 @@ -export * from './shared'; +export * from './core'; export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts index 17822c8a3e..0cf424afd7 100644 --- a/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts +++ b/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { Hero, HeroService } from './heroes'; -import { ExceptionService, SpinnerService, ToastService } from './shared'; +import { ExceptionService, SpinnerService, ToastService } from './core'; @Component({ moduleId: module.id, diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/exception.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/core/exception.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/shared/exception.service.ts rename to public/docs/_examples/style-guide/ts/03-06/app/core/exception.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/03-06/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/core/spinner/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/index.ts rename to public/docs/_examples/style-guide/ts/03-06/app/core/spinner/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.component.ts b/public/docs/_examples/style-guide/ts/03-06/app/core/spinner/spinner.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.component.ts rename to public/docs/_examples/style-guide/ts/03-06/app/core/spinner/spinner.component.ts diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/core/spinner/spinner.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.service.ts rename to public/docs/_examples/style-guide/ts/03-06/app/core/spinner/spinner.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/core/toast/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/shared/toast/index.ts rename to public/docs/_examples/style-guide/ts/03-06/app/core/toast/index.ts diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/03-06/app/core/toast/toast.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.component.ts rename to public/docs/_examples/style-guide/ts/03-06/app/core/toast/toast.component.ts diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/core/toast/toast.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.service.ts rename to public/docs/_examples/style-guide/ts/03-06/app/core/toast/toast.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.avoid.ts index 6c15ba46bd..bb02f3a9ae 100644 --- a/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.avoid.ts +++ b/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.avoid.ts @@ -2,7 +2,7 @@ // #docregion example /* avoid */ -import { ExceptionService, SpinnerService, ToastService } from '../../shared'; +import { ExceptionService, SpinnerService, ToastService } from '../../core'; import { Http, Response } from '@angular/http'; import { Injectable } from '@angular/core'; import { Hero } from './hero.model'; diff --git a/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.ts index 817fdbead1..a1711e0fe4 100644 --- a/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.ts +++ b/public/docs/_examples/style-guide/ts/03-06/app/heroes/shared/hero.service.ts @@ -4,7 +4,7 @@ import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http'; import { Hero } from './hero.model'; -import { ExceptionService, SpinnerService, ToastService } from '../../shared'; +import { ExceptionService, SpinnerService, ToastService } from '../../core'; // #enddocregion example @Injectable() diff --git a/public/docs/_examples/style-guide/ts/03-06/app/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/index.ts index 251d78ac56..cf861e261a 100644 --- a/public/docs/_examples/style-guide/ts/03-06/app/index.ts +++ b/public/docs/_examples/style-guide/ts/03-06/app/index.ts @@ -1,3 +1,3 @@ export * from './heroes'; -export * from './shared'; +export * from './core'; export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.component.ts index dd0bba5eba..e1c1ae6665 100644 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.component.ts +++ b/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit } from '@angular/core'; -import { ToastService } from './toast.service'; +import { ToastService } from '../../core'; @Component({ selector: 'toh-toast', diff --git a/public/docs/_examples/style-guide/ts/04-14/app/app.component.ts b/public/docs/_examples/style-guide/ts/04-08/app/app.component.ts similarity index 91% rename from public/docs/_examples/style-guide/ts/04-14/app/app.component.ts rename to public/docs/_examples/style-guide/ts/04-08/app/app.component.ts index 0e43893f7f..fdd8e6ef56 100644 --- a/public/docs/_examples/style-guide/ts/04-14/app/app.component.ts +++ b/public/docs/_examples/style-guide/ts/04-08/app/app.component.ts @@ -1,3 +1,4 @@ +// #docregion import { Component } from '@angular/core'; @Component({ diff --git a/public/docs/_examples/style-guide/ts/04-08/app/app.module.ts b/public/docs/_examples/style-guide/ts/04-08/app/app.module.ts new file mode 100644 index 0000000000..e24bf2c038 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-08/app/app.module.ts @@ -0,0 +1,28 @@ +// #docplaster +// #docregion +// #docregion example +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion example +import { RouterModule } from '@angular/router'; +// #docregion example + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes/heroes.component'; + +@NgModule({ + imports: [ + BrowserModule, +// #enddocregion example + RouterModule.forChild([{ path: '04-08', component: AppComponent }]) +// #docregion example + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + entryComponents: [ AppComponent ] +}) +export class AppModule {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-08/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/04-08/app/heroes/heroes.component.html new file mode 100644 index 0000000000..1244e68a4a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-08/app/heroes/heroes.component.html @@ -0,0 +1 @@ +
This is heroes component
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/04-08/app/heroes/heroes.component.ts similarity index 54% rename from public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.ts rename to public/docs/_examples/style-guide/ts/04-08/app/heroes/heroes.component.ts index e12f8af5d9..b3a76ff120 100644 --- a/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.ts +++ b/public/docs/_examples/style-guide/ts/04-08/app/heroes/heroes.component.ts @@ -1,21 +1,21 @@ +// #docplaster // #docregion +// #docregion example import { Component, OnInit } from '@angular/core'; -import { Hero } from './shared'; -// #docregion example -import { Logger } from '../shared'; -// #enddocregion example - @Component({ + // #enddocregion example moduleId: module.id, + // #docregion example selector: 'toh-heroes', - templateUrl: 'heroes.component.html', - styleUrls: ['heroes.component.css'], - providers: [Logger] + templateUrl: 'heroes.component.html' }) export class HeroesComponent implements OnInit { - heroes: Hero[]; - selectedHero: Hero; + // #enddocregion example + // #docregion example + constructor() { } ngOnInit() { } } +// #enddocregion example + diff --git a/public/docs/_examples/style-guide/ts/04-10/app/app.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/app.component.ts index aef486d9a2..fdd8e6ef56 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/app.component.ts +++ b/public/docs/_examples/style-guide/ts/04-10/app/app.component.ts @@ -5,5 +5,4 @@ import { Component } from '@angular/core'; selector: 'sg-app', template: '' }) -export class AppComponent { - } +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/app.module.ts b/public/docs/_examples/style-guide/ts/04-10/app/app.module.ts index dec8d2c6f2..78106657ad 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/app.module.ts +++ b/public/docs/_examples/style-guide/ts/04-10/app/app.module.ts @@ -1,8 +1,13 @@ +// #docplaster +// #docregion +// #docregion example import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; -import { RouterModule } from '@angular/router'; +// #enddocregion example +import { RouterModule } from '@angular/router'; +// #docregion example -import { AppComponent } from './app.component'; +import { AppComponent } from './app.component'; import { HeroesComponent } from './heroes/heroes.component'; import { SharedModule } from './shared/shared.module'; @@ -10,7 +15,9 @@ import { SharedModule } from './shared/shared.module'; imports: [ BrowserModule, SharedModule, +// #enddocregion example RouterModule.forChild([{ path: '04-10', component: AppComponent }]) +// #docregion example ], declarations: [ AppComponent, @@ -20,3 +27,4 @@ import { SharedModule } from './shared/shared.module'; entryComponents: [ AppComponent ] }) export class AppModule {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.avoid.ts b/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.avoid.ts deleted file mode 100644 index 2d10e7b3c3..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.avoid.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* tslint:disable:no-unused-variable */ -// #docregion -// #docregion example -/* avoid */ - -import { Component, OnInit } from '@angular/core'; - -import { CONFIG } from '../shared/config'; -import { EntityService } from '../shared/entity.service'; -import { ExceptionService } from '../shared/exception.service'; -import { FilterTextComponent } from '../shared/filter-text/filter-text.component'; -import { InitCapsPipe } from '../shared/init-caps.pipe'; -import { SpinnerService } from '../shared/spinner/spinner.service'; -import { ToastService } from '../shared/toast/toast.service'; - -@Component({ - selector: 'toh-heroes', - templateUrl: 'app/+heroes/heroes.component.html' -}) -export class HeroesComponent implements OnInit { - constructor() { } - - ngOnInit() { } -} -// #enddocregion example - diff --git a/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.html index 1244e68a4a..170f76aee1 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.html +++ b/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.html @@ -1 +1,8 @@ +
This is heroes component
+ + diff --git a/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.ts index 1443a5b445..14eb56a7f0 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.ts +++ b/public/docs/_examples/style-guide/ts/04-10/app/heroes/heroes.component.ts @@ -3,29 +3,36 @@ // #docregion example import { Component, OnInit } from '@angular/core'; -import { - CONFIG, - EntityService, - ExceptionService, - SpinnerService, - ToastService -} from '../shared'; +import { FilterTextService } from '../shared/filter-text/filter-text.service'; @Component({ // #enddocregion example moduleId: module.id, - providers: [EntityService, ExceptionService, SpinnerService, ToastService], // #docregion example selector: 'toh-heroes', templateUrl: 'heroes.component.html' }) export class HeroesComponent implements OnInit { // #enddocregion example - urls = CONFIG.baseUrls; // #docregion example - constructor() { } + filteredHeroes: any[] = []; - ngOnInit() { } + constructor(private filterService: FilterTextService) { } + + heroes = [ + { id: 1, name: 'Windstorm' }, + { id: 2, name: 'Bombasto' }, + { id: 3, name: 'Magneta' }, + { id: 4, name: 'Tornado' } + ]; + + filterChanged(searchText: string) { + this.filteredHeroes = this.filterService.filter(searchText, ['id', 'name'], this.heroes); + } + + ngOnInit() { + this.filteredHeroes = this.heroes; + } } // #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/config.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/config.ts deleted file mode 100644 index cf7281ecf1..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -export let CONFIG = { - baseUrls: { - heroes: 'api/heroes.json', - villains: 'api/villains.json' - } -}; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/entity.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/entity.service.ts deleted file mode 100644 index 2d2a13db6d..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/entity.service.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class EntityService { } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/exception.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/exception.service.ts deleted file mode 100644 index 7180c88e6b..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/exception.service.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class ExceptionService { } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.component.ts index 8b058c7ba7..e23987d2f0 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.component.ts +++ b/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.component.ts @@ -1,19 +1,27 @@ +// #docregion import { Component, EventEmitter, Output } from '@angular/core'; @Component({ moduleId: module.id, selector: 'toh-filter-text', - template: '
filter
' + template: '' }) export class FilterTextComponent { @Output() changed: EventEmitter; + filter: string; - constructor() { } + constructor() { + this.changed = new EventEmitter(); + } clear() { + this.filter = ''; } filterChanged(event: any) { + event.preventDefault(); + console.log(`Filter Changed: ${this.filter}`); + this.changed.emit(this.filter); } } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.service.ts index 9c8cc0ce3f..87978e10e5 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.service.ts +++ b/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.service.ts @@ -1,11 +1,30 @@ +// #docregion import { Injectable } from '@angular/core'; @Injectable() -export class FilterService { - constructor() { } +export class FilterTextService { + constructor() { + console.log('Created an instance of FilterTextService'); + } filter(data: string, props: Array, originalList: Array) { let filteredList: any[]; + if (data && props && originalList) { + data = data.toLowerCase(); + let filtered = originalList.filter(item => { + let match = false; + for (let prop of props) { + if (item[prop].toString().toLowerCase().indexOf(data) > -1) { + match = true; + break; + } + }; + return match; + }); + filteredList = filtered; + } else { + filteredList = originalList; + } return filteredList; } } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/index.ts deleted file mode 100644 index 4641503ec4..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './filter-text.component'; -export * from './filter-text.service'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/index.ts deleted file mode 100644 index e4f31e4c62..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -// #docregion example -export * from './config'; -export * from './entity.service'; -export * from './exception.service'; -export * from './filter-text'; -export * from './init-caps.pipe'; -export * from './modal'; -export * from './nav'; -export * from './spinner'; -export * from './toast'; -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/init-caps.pipe.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/init-caps.pipe.ts index a7bd0c6521..5019bcb234 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/init-caps.pipe.ts +++ b/public/docs/_examples/style-guide/ts/04-10/app/shared/init-caps.pipe.ts @@ -1,8 +1,7 @@ +// #docregion import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { transform = (value: string) => value; } - - diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/index.ts deleted file mode 100644 index 03bebd34d4..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './modal.component'; -export * from './modal.service'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.component.ts deleted file mode 100644 index ab62348e10..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ModalService } from './modal.service'; - -@Component({ - moduleId: module.id, - selector: 'toh-modal-confirm', - template: '
modal
' -}) -export class ModalComponent implements OnInit { - constructor(modalService: ModalService) { } - - ngOnInit() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.service.ts deleted file mode 100644 index d5fad3a815..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.service.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class ModalService { - activate: (message?: string, title?: string) => Promise; -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/index.ts deleted file mode 100644 index 4236f3e9e1..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// #docregion -export * from './nav.component'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/nav.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/nav.component.ts deleted file mode 100644 index 97d6313cf3..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/nav.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ModalService } from '../'; - -@Component({ - moduleId: module.id, - selector: 'toh-nav', - template: '
nav
' -}) -export class NavComponent implements OnInit { - - ngOnInit() { } - - constructor(private modalService: ModalService) { } - - resetDb() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/shared.module.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/shared.module.ts index 6500b28330..6160abcc84 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/shared.module.ts +++ b/public/docs/_examples/style-guide/ts/04-10/app/shared/shared.module.ts @@ -1,20 +1,24 @@ +// #docregion import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; -import { FilterTextComponent, - InitCapsPipe, - ModalComponent, - NavComponent, - SpinnerComponent } from './'; - -const declarations = [ - FilterTextComponent, InitCapsPipe, ModalComponent, - NavComponent, SpinnerComponent, -]; +import { FilterTextComponent } from './filter-text/filter-text.component'; +import { FilterTextService } from './filter-text/filter-text.service'; +import { InitCapsPipe } from './init-caps.pipe'; @NgModule({ - imports: [ BrowserModule ], - declarations: declarations, - exports: declarations + imports: [CommonModule, FormsModule], + declarations: [ + FilterTextComponent, + InitCapsPipe + ], + providers: [FilterTextService], + exports: [ + CommonModule, + FormsModule, + FilterTextComponent, + InitCapsPipe + ] }) export class SharedModule { } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/index.ts deleted file mode 100644 index 1d619300c0..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './spinner.component'; -export * from './spinner.service'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.component.ts deleted file mode 100644 index 1fd2a01500..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; - -import { SpinnerService } from './spinner.service'; - -@Component({ - selector: 'toh-spinner', - template: '
spinner
' -}) - -export class SpinnerComponent implements OnDestroy, OnInit { - constructor(private spinnerService: SpinnerService) { } - - ngOnInit() { } - - ngOnDestroy() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.service.ts deleted file mode 100644 index ad5d2ed6e0..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.service.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Injectable } from '@angular/core'; - -export interface ISpinnerState { } - -@Injectable() -export class SpinnerService { - spinnerState: any; - - show() { } - - hide() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/index.ts deleted file mode 100644 index 01b41aff98..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './toast.component'; -export * from './toast.service'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.service.ts deleted file mode 100644 index e92e75ee45..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.service.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class ToastService { - activate: (message?: string, title?: string) => void; -} diff --git a/public/docs/_examples/style-guide/ts/04-11/app/app.component.ts b/public/docs/_examples/style-guide/ts/04-11/app/app.component.ts new file mode 100644 index 0000000000..693619a982 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/app.component.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'toh-app', + template: ` + + + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/04-11/app/app.module.ts b/public/docs/_examples/style-guide/ts/04-11/app/app.module.ts new file mode 100644 index 0000000000..ef3c156bcf --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/app.module.ts @@ -0,0 +1,30 @@ +// #docplaster +// #docregion +// #docregion example +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion example +import { RouterModule } from '@angular/router'; +// #docregion example + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes/heroes.component'; +import { CoreModule } from './core/core.module'; + +@NgModule({ + imports: [ + BrowserModule, + CoreModule, +// #enddocregion example + RouterModule.forChild([{ path: '04-11', component: AppComponent }]) +// #docregion example + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + entryComponents: [ AppComponent ] +}) +export class AppModule {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/core.module.ts b/public/docs/_examples/style-guide/ts/04-11/app/core/core.module.ts new file mode 100644 index 0000000000..4ba5c79a14 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/core.module.ts @@ -0,0 +1,19 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { LoggerService } from './logger.service'; +import { NavComponent } from './nav/nav.component'; +import { SpinnerComponent } from './spinner/spinner.component'; +import { SpinnerService } from './spinner/spinner.service'; + +@NgModule({ + imports: [ + CommonModule // we use ngFor + ], +  exports: [NavComponent, SpinnerComponent], +  declarations: [NavComponent, SpinnerComponent], + providers: [LoggerService, SpinnerService] +}) +export class CoreModule { } + diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/index.ts b/public/docs/_examples/style-guide/ts/04-11/app/core/index.ts new file mode 100644 index 0000000000..7d2092f804 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/index.ts @@ -0,0 +1,5 @@ +// #docregion +export * from './logger.service'; +export * from './rxjs-extensions'; +export * from './spinner/spinner.service'; +export * from './nav/nav.component'; diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/logger.service.ts b/public/docs/_examples/style-guide/ts/04-11/app/core/logger.service.ts new file mode 100644 index 0000000000..9c7080f07a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/logger.service.ts @@ -0,0 +1,13 @@ +// #docregion +import { Injectable } from '@angular/core'; + +@Injectable() +export class LoggerService { + log(msg: string) { + console.log(msg); + } + + error(msg: string) { + console.error(msg); + } +} diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.css b/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.css new file mode 100644 index 0000000000..c7903fd25c --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.css @@ -0,0 +1,63 @@ +/*#docregion*/ +.mdl-layout__header { + display: flex; + position: fixed; + background-color: #222; +} + +.nav-link { + padding: 0 1em; + width: 100px; + color: rgba(255,255,255,.6); + text-align: center; + text-decoration: none; +} + +.nav-link.router-link-active { + color: rgba(255,255,255, 1); +} + +.nav-link.router-link-active::after { + height: 3px; + width: 100%; + display: block; + content: " "; + bottom: 0; + left: 0; + position: inherit; + background: rgb(83,109,254); +} + +.md-title-icon > i { + background-image: url("assets/ng.png"); + background-repeat: no-repeat; + background-position: center center; + padding: 1em 2em; +} + +.mdl-layout__header-row { + height: 56px; + padding: 0 16px 0 72px; + padding-left: 8px; + background-color: #673AB7; + background: #0033FF; + background-color: #222; +} + +#reset-button { + position: fixed; + right: 2em; + top: 1em; +} + +@media (max-width: 480px) { + #reset-button { + display: none + } +} + +@media (max-width: 320px) { + a.nav-link { + font-size: 12px; + } +} diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.html b/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.html new file mode 100644 index 0000000000..b3c7e441e0 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.html @@ -0,0 +1,14 @@ + +
+
+

Tour of Heroes

+
+ +
+
diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.ts b/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.ts new file mode 100644 index 0000000000..ba8796251b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/nav/nav.component.ts @@ -0,0 +1,20 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'toh-nav', + templateUrl: 'nav.component.html', + styleUrls: ['nav.component.css'], +}) +export class NavComponent implements OnInit { + menuItems = [ + 'Heroes', + 'Villains', + 'Other' + ]; + + ngOnInit() { } + + constructor() { } +} diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/rxjs-extensions.ts b/public/docs/_examples/style-guide/ts/04-11/app/core/rxjs-extensions.ts new file mode 100644 index 0000000000..870dd7af2b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/rxjs-extensions.ts @@ -0,0 +1,7 @@ +// #docregion +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/finally'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/mergeMap'; +import 'rxjs/add/observable/of'; diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.css b/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.css new file mode 100644 index 0000000000..afad0fe8e3 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.css @@ -0,0 +1,21 @@ +/*#docregion*/ +.spinner { + position: absolute; + left: 7em; + top: 20em; + position: absolute; + background-color: blue; + height: .3em; + width: 6em; + margin:-60px 0 0 -60px; + -webkit-animation:spin 4s linear infinite; + -moz-animation:spin 4s linear infinite; + animation:spin 4s linear infinite; +} +@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } } +@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } } +@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } } + +.spinner-hidden { + display:none; +} diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.html b/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.html new file mode 100644 index 0000000000..a07e3378c0 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.html @@ -0,0 +1,2 @@ + +
diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.ts b/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.ts new file mode 100644 index 0000000000..7260eb8d88 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.component.ts @@ -0,0 +1,36 @@ +// #docregion +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs/Subscription'; + +import { LoggerService } from '../logger.service'; +import { SpinnerState, SpinnerService } from './spinner.service'; + +@Component({ + moduleId: module.id, + selector: 'toh-spinner', + templateUrl: 'spinner.component.html', + styleUrls: ['spinner.component.css'] +}) +export class SpinnerComponent implements OnDestroy, OnInit { + visible = false; + + private spinnerStateChanged: Subscription; + + constructor( + private loggerService: LoggerService, + private spinnerService: SpinnerService + ) { } + + ngOnInit() { + console.log(this.visible); + this.spinnerStateChanged = this.spinnerService.spinnerState + .subscribe((state: SpinnerState) => { + this.visible = state.show; + this.loggerService.log(`visible=${this.visible}`); + }); + } + + ngOnDestroy() { + this.spinnerStateChanged.unsubscribe(); + } +} diff --git a/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.service.ts b/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.service.ts new file mode 100644 index 0000000000..85e366c43e --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/core/spinner/spinner.service.ts @@ -0,0 +1,24 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs/Subject'; + +export interface SpinnerState { + show: boolean; +} + +@Injectable() +export class SpinnerService { + private spinnerSubject = new Subject(); + + spinnerState = this.spinnerSubject.asObservable(); + + constructor() { } + + show() { + this.spinnerSubject.next({ show: true }); + } + + hide() { + this.spinnerSubject.next({ show: false }); + } +} diff --git a/public/docs/_examples/style-guide/ts/04-11/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/04-11/app/heroes/heroes.component.html new file mode 100644 index 0000000000..9035a4b8ff --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/heroes/heroes.component.html @@ -0,0 +1,12 @@ + +
+ + + +
    +
  • + {{hero.name}} +
  • +
+ +
diff --git a/public/docs/_examples/style-guide/ts/04-11/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/04-11/app/heroes/heroes.component.ts new file mode 100644 index 0000000000..b15d2dc8bc --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-11/app/heroes/heroes.component.ts @@ -0,0 +1,41 @@ +// #docplaster +// #docregion +// #docregion example +import { Component } from '@angular/core'; + +import { LoggerService } from '../core/logger.service'; +import { SpinnerService } from '../core/spinner/spinner.service'; + +@Component({ + // #enddocregion example + moduleId: module.id, + // #docregion example + selector: 'toh-heroes', + templateUrl: 'heroes.component.html' +}) +export class HeroesComponent { + // #enddocregion example + // #docregion example + heroes: any[]; + + constructor( + private loggerService: LoggerService, + private spinnerService: SpinnerService + ) { } + + getHeroes() { + this.loggerService.log(`Getting heroes`); + this.spinnerService.show(); + setTimeout(() => { + this.heroes = [ + { id: 1, name: 'Windstorm' }, + { id: 2, name: 'Bombasto' }, + { id: 3, name: 'Magneta' }, + { id: 4, name: 'Tornado' } + ]; + this.loggerService.log(`We have ${HeroesComponent.length} heroes`); + this.spinnerService.hide(); + }, 2000); + } +} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-12/app/app.component.ts b/public/docs/_examples/style-guide/ts/04-12/app/app.component.ts new file mode 100644 index 0000000000..dc85b06e9f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/app.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'toh-app', + template: ` + + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/04-12/app/app.module.ts b/public/docs/_examples/style-guide/ts/04-12/app/app.module.ts new file mode 100644 index 0000000000..7c9fb44182 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/app.module.ts @@ -0,0 +1,30 @@ +// #docplaster +// #docregion +// #docregion example +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion example +import { RouterModule } from '@angular/router'; +// #docregion example + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes/heroes.component'; +import { CoreModule } from './core/core.module'; + +@NgModule({ + imports: [ + BrowserModule, + CoreModule, +// #enddocregion example + RouterModule.forChild([{ path: '04-12', component: AppComponent }]) +// #docregion example + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + entryComponents: [ AppComponent ] +}) +export class AppModule {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-12/app/core/core.module.ts b/public/docs/_examples/style-guide/ts/04-12/app/core/core.module.ts new file mode 100644 index 0000000000..069141bf2a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/core/core.module.ts @@ -0,0 +1,21 @@ +// #docregion +import { NgModule, Optional, SkipSelf } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { LoggerService } from './logger.service'; +import { NavComponent } from './nav/nav.component'; +import { throwIfAlreadyLoaded } from './module-import-guard'; + +@NgModule({ + imports: [ + CommonModule // we use ngFor + ], +  exports: [NavComponent], +  declarations: [NavComponent], + providers: [LoggerService] +}) +export class CoreModule { + constructor( @Optional() @SkipSelf() parentModule: CoreModule) { + throwIfAlreadyLoaded(parentModule, 'CoreModule'); + } +} diff --git a/public/docs/_examples/style-guide/ts/04-12/app/core/index.ts b/public/docs/_examples/style-guide/ts/04-12/app/core/index.ts new file mode 100644 index 0000000000..8768b77f41 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/core/index.ts @@ -0,0 +1,3 @@ +// #docregion +export * from './logger.service'; +export * from './nav/nav.component'; diff --git a/public/docs/_examples/style-guide/ts/04-12/app/core/logger.service.ts b/public/docs/_examples/style-guide/ts/04-12/app/core/logger.service.ts new file mode 100644 index 0000000000..9c7080f07a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/core/logger.service.ts @@ -0,0 +1,13 @@ +// #docregion +import { Injectable } from '@angular/core'; + +@Injectable() +export class LoggerService { + log(msg: string) { + console.log(msg); + } + + error(msg: string) { + console.error(msg); + } +} diff --git a/public/docs/_examples/style-guide/ts/04-12/app/core/module-import-guard.ts b/public/docs/_examples/style-guide/ts/04-12/app/core/module-import-guard.ts new file mode 100644 index 0000000000..5248b15b2e --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/core/module-import-guard.ts @@ -0,0 +1,6 @@ +// #docregion +export function throwIfAlreadyLoaded(parentModule: any, moduleName: string) { + if (parentModule) { + throw new Error(`${moduleName} has already been loaded. Import Core modules in the AppModule only.`); + } +} diff --git a/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.css b/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.css new file mode 100644 index 0000000000..c7903fd25c --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.css @@ -0,0 +1,63 @@ +/*#docregion*/ +.mdl-layout__header { + display: flex; + position: fixed; + background-color: #222; +} + +.nav-link { + padding: 0 1em; + width: 100px; + color: rgba(255,255,255,.6); + text-align: center; + text-decoration: none; +} + +.nav-link.router-link-active { + color: rgba(255,255,255, 1); +} + +.nav-link.router-link-active::after { + height: 3px; + width: 100%; + display: block; + content: " "; + bottom: 0; + left: 0; + position: inherit; + background: rgb(83,109,254); +} + +.md-title-icon > i { + background-image: url("assets/ng.png"); + background-repeat: no-repeat; + background-position: center center; + padding: 1em 2em; +} + +.mdl-layout__header-row { + height: 56px; + padding: 0 16px 0 72px; + padding-left: 8px; + background-color: #673AB7; + background: #0033FF; + background-color: #222; +} + +#reset-button { + position: fixed; + right: 2em; + top: 1em; +} + +@media (max-width: 480px) { + #reset-button { + display: none + } +} + +@media (max-width: 320px) { + a.nav-link { + font-size: 12px; + } +} diff --git a/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.html b/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.html new file mode 100644 index 0000000000..b3c7e441e0 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.html @@ -0,0 +1,14 @@ + +
+
+

Tour of Heroes

+
+ +
+
diff --git a/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.ts b/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.ts new file mode 100644 index 0000000000..ba8796251b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/core/nav/nav.component.ts @@ -0,0 +1,20 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'toh-nav', + templateUrl: 'nav.component.html', + styleUrls: ['nav.component.css'], +}) +export class NavComponent implements OnInit { + menuItems = [ + 'Heroes', + 'Villains', + 'Other' + ]; + + ngOnInit() { } + + constructor() { } +} diff --git a/public/docs/_examples/style-guide/ts/04-12/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/04-12/app/heroes/heroes.component.html new file mode 100644 index 0000000000..9035a4b8ff --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/heroes/heroes.component.html @@ -0,0 +1,12 @@ + +
+ + + +
    +
  • + {{hero.name}} +
  • +
+ +
diff --git a/public/docs/_examples/style-guide/ts/04-12/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/04-12/app/heroes/heroes.component.ts new file mode 100644 index 0000000000..ee60b88178 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/04-12/app/heroes/heroes.component.ts @@ -0,0 +1,33 @@ +// #docplaster +// #docregion +// #docregion example +import { Component } from '@angular/core'; + +import { LoggerService } from '../core/logger.service'; + +@Component({ + // #enddocregion example + moduleId: module.id, + // #docregion example + selector: 'toh-heroes', + templateUrl: 'heroes.component.html' +}) +export class HeroesComponent { + // #enddocregion example + // #docregion example + heroes: any[]; + + constructor(private loggerService: LoggerService) { } + + getHeroes() { + this.loggerService.log(`Getting heroes`); + this.heroes = [ + { id: 1, name: 'Windstorm' }, + { id: 2, name: 'Bombasto' }, + { id: 3, name: 'Magneta' }, + { id: 4, name: 'Tornado' } + ]; + this.loggerService.log(`We have ${HeroesComponent.length} heroes`); + } +} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts b/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts deleted file mode 100644 index dc96beac4c..0000000000 --- a/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts +++ /dev/null @@ -1,11 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -// #docregion example -import { HeroesComponent } from './heroes'; -// #enddocregion example - -@Component({ - selector: 'toh-app' -}) -export class AppComponent {} diff --git a/public/docs/_examples/style-guide/ts/04-13/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/04-13/app/heroes/index.ts deleted file mode 100644 index 45d52e8c70..0000000000 --- a/public/docs/_examples/style-guide/ts/04-13/app/heroes/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Needed for the .avoid code to compile -export const HeroesComponent = 42; diff --git a/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.css b/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.css deleted file mode 100644 index 82f0c1d0ab..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.css +++ /dev/null @@ -1,28 +0,0 @@ -/* #docregion */ -.heroes { - margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; -} -.heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} diff --git a/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.html deleted file mode 100644 index b6bf75ef1a..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/heroes/heroes.component.html +++ /dev/null @@ -1,12 +0,0 @@ - -
-

My Heroes

-
    -
  • - {{hero.id}} {{hero.name}} -
  • -
-
-

{{selectedHero.name | uppercase}} is my hero

-
-
diff --git a/public/docs/_examples/style-guide/ts/04-14/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/heroes/index.ts deleted file mode 100644 index a8d7f1d422..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/heroes/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './heroes.component'; diff --git a/public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/hero.model.ts deleted file mode 100644 index 8f7cc205c8..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/hero.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -// #docregion -export class Hero { - id: number; - name: string; -} diff --git a/public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/index.ts deleted file mode 100644 index 0dceb684c4..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/heroes/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './hero.model'; diff --git a/public/docs/_examples/style-guide/ts/04-14/app/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/index.ts deleted file mode 100644 index 251d78ac56..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './heroes'; -export * from './shared'; -export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/04-14/app/shared/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/shared/index.ts deleted file mode 100644 index 6820e22fc7..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './logger.service'; diff --git a/public/docs/_examples/style-guide/ts/04-14/app/shared/logger.service.ts b/public/docs/_examples/style-guide/ts/04-14/app/shared/logger.service.ts deleted file mode 100644 index b1f8c7ff21..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/shared/logger.service.ts +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -@Injectable() -export class Logger { - - constructor() { } - -} diff --git a/public/docs/_examples/style-guide/ts/06-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/06-03/app/app.component.ts index 5f4ea8dce5..0d0a7d107b 100644 --- a/public/docs/_examples/style-guide/ts/06-03/app/app.component.ts +++ b/public/docs/_examples/style-guide/ts/06-03/app/app.component.ts @@ -2,6 +2,8 @@ import { Component } from '@angular/core'; @Component({ selector: 'sg-app', - template: '' + template: ` + + ` }) export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/06-03/app/app.module.ts b/public/docs/_examples/style-guide/ts/06-03/app/app.module.ts index 8677138eef..b19f3fdc00 100644 --- a/public/docs/_examples/style-guide/ts/06-03/app/app.module.ts +++ b/public/docs/_examples/style-guide/ts/06-03/app/app.module.ts @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; -import { ValidatorDirective } from './shared'; +import { ValidatorDirective, Validator2Directive } from './shared'; @NgModule({ imports: [ @@ -10,7 +10,7 @@ import { ValidatorDirective } from './shared'; ], declarations: [ AppComponent, - ValidatorDirective + ValidatorDirective, Validator2Directive ], exports: [ AppComponent ] }) diff --git a/public/docs/_examples/style-guide/ts/06-03/app/shared/index.ts b/public/docs/_examples/style-guide/ts/06-03/app/shared/index.ts index 2168f8b2c6..ba25e4c458 100644 --- a/public/docs/_examples/style-guide/ts/06-03/app/shared/index.ts +++ b/public/docs/_examples/style-guide/ts/06-03/app/shared/index.ts @@ -1 +1,2 @@ export * from './validator.directive'; +export * from './validator2.directive'; diff --git a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.avoid.ts b/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.avoid.ts deleted file mode 100644 index c9b724dc53..0000000000 --- a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.avoid.ts +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion -import { Directive, HostBinding, HostListener } from '@angular/core'; - -// #docregion example -/* avoid */ - -@Directive({ - selector: '[tohValidator]', - host: { - '(mouseenter)': 'onMouseEnter()', - 'attr.role': 'button' - } -}) -export class ValidatorDirective { - role = 'button'; - onMouseEnter() { - // do work - } -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.ts b/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.ts index 4271da0ef6..d9e32c017f 100644 --- a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.ts +++ b/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.ts @@ -1,7 +1,6 @@ // #docregion import { Directive, HostBinding, HostListener } from '@angular/core'; -// #docregion example @Directive({ selector: '[tohValidator]' }) @@ -11,4 +10,3 @@ export class ValidatorDirective { // do work } } -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator2.directive.ts b/public/docs/_examples/style-guide/ts/06-03/app/shared/validator2.directive.ts new file mode 100644 index 0000000000..7936a83cb1 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/06-03/app/shared/validator2.directive.ts @@ -0,0 +1,16 @@ +// #docregion +import { Directive } from '@angular/core'; + +@Directive({ + selector: '[tohValidator2]', + host: { + 'attr.role': 'button', + '(mouseenter)': 'onMouseEnter()' + } +}) +export class Validator2Directive { + role = 'button'; + onMouseEnter() { + // do work + } +} diff --git a/public/docs/_examples/style-guide/ts/app/app.routes.ts b/public/docs/_examples/style-guide/ts/app/app.routes.ts index 1fb26f08ea..bce6b4df06 100644 --- a/public/docs/_examples/style-guide/ts/app/app.routes.ts +++ b/public/docs/_examples/style-guide/ts/app/app.routes.ts @@ -1,58 +1,8 @@ import { Routes } from '@angular/router'; import { AppComponent as S0101 } from '../01-01/app'; -// import { AppComponent as S0207 } from '../02-07/app'; -// import { AppComponent as S0208 } from '../02-08/app'; -// import { AppComponent as S0301 } from '../03-01/app'; -// import { AppComponent as S0302 } from '../03-02/app'; -// import { AppComponent as S0303 } from '../03-03/app'; -// import { AppComponent as S0304 } from '../03-04/app'; -// import { AppComponent as S0305 } from '../03-05/app'; -// import { AppComponent as S0306 } from '../03-06/app'; -// import { AppComponent as S0410 } from '../04-10/app'; -// import { AppComponent as S0414 } from '../04-14/app'; -// import { AppComponent as S0502 } from '../05-02/app'; -// import { AppComponent as S0503 } from '../05-03/app'; -// import { AppComponent as S0504 } from '../05-04/app'; -// import { AppComponent as S0512 } from '../05-12/app'; -// import { AppComponent as S0513 } from '../05-13/app'; -// import { AppComponent as S0514 } from '../05-14/app'; -// import { AppComponent as S0515 } from '../05-15/app'; -// import { AppComponent as S0516 } from '../05-16/app'; -// import { AppComponent as S0517 } from '../05-17/app'; -// import { AppComponent as S0601 } from '../06-01/app'; -// import { AppComponent as S0603 } from '../06-03/app'; -// import { AppComponent as S0701 } from '../07-01/app'; -// import { AppComponent as S0703 } from '../07-03/app'; -// import { AppComponent as S0704 } from '../07-04/app'; -// import { AppComponent as S0901 } from '../09-01/app'; export const routes: Routes = [ { path: '', redirectTo: '/01-01', pathMatch: 'full' }, { path: '01-01', component: S0101 }, - // { path: '02-07', component: S0207 }, - // { path: '02-08', component: S0208 }, - // { path: '03-01', component: S0301 }, - // { path: '03-02', component: S0302 }, - // { path: '03-03', component: S0303 }, - // { path: '03-04', component: S0304 }, - // { path: '03-05', component: S0305 }, - // { path: '03-06', component: S0306 }, - ///////////////////{ path: '04-10', component: S0410 }, - // { path: '04-14', component: S0414 }, - // { path: '05-02', component: S0502 }, - // { path: '05-03', component: S0503 }, - // { path: '05-04', component: S0504 }, - // { path: '05-12', component: S0512 }, - // { path: '05-13', component: S0513 }, - // { path: '05-14', component: S0514 }, - // { path: '05-15', component: S0515 }, - // { path: '05-16', component: S0516 }, - // { path: '05-17', component: S0517 }, - // { path: '06-01', component: S0601 }, - // { path: '06-03', component: S0603 }, - // { path: '07-01', component: S0701 }, - // { path: '07-03', component: S0703 }, - // { path: '07-04', component: S0704 }, - // { path: '09-01', component: S0901 }, ]; diff --git a/public/docs/_examples/style-guide/ts/app/main.ts b/public/docs/_examples/style-guide/ts/app/main.ts index 792f873167..eef534bd4d 100644 --- a/public/docs/_examples/style-guide/ts/app/main.ts +++ b/public/docs/_examples/style-guide/ts/app/main.ts @@ -16,6 +16,7 @@ import { HeroData } from './hero-data'; import { AppComponent } from './app.component'; import * as s0101 from '../01-01/app/app.module'; +import * as s0205 from '../02-05/app/app.module'; import * as s0207 from '../02-07/app/app.module'; import * as s0208 from '../02-08/app/app.module'; import * as s0301 from '../03-01/app/app.module'; @@ -23,8 +24,10 @@ import * as s0302 from '../03-02/app/app.module'; import * as s0303 from '../03-03/app/app.module'; import * as s0304 from '../03-04/app/app.module'; import * as s0306 from '../03-06/app/app.module'; +import * as s0408 from '../04-08/app/app.module'; import * as s0410 from '../04-10/app/app.module'; -import * as s0414 from '../04-14/app/app.module'; +import * as s0411 from '../04-11/app/app.module'; +import * as s0412 from '../04-12/app/app.module'; import * as s0502 from '../05-02/app/app.module'; import * as s0503 from '../05-03/app/app.module'; import * as s0504 from '../05-04/app/app.module'; @@ -49,6 +52,7 @@ const moduleMetadata = { InMemoryWebApiModule.forRoot(HeroData), s0101.AppModule, + s0205.AppModule, s0207.AppModule, s0208.AppModule, s0301.AppModule, @@ -56,8 +60,10 @@ const moduleMetadata = { s0303.AppModule, s0304.AppModule, s0306.AppModule, + s0408.AppModule, s0410.AppModule, - s0414.AppModule, + s0411.AppModule, + s0412.AppModule, s0502.AppModule, s0503.AppModule, s0504.AppModule, @@ -74,7 +80,6 @@ const moduleMetadata = { s0704.AppModule, s0901.AppModule, - RouterModule.forRoot([ { path: '', redirectTo: '/01-01', pathMatch: 'full' } ], {/* enableTracing: true */}), diff --git a/public/docs/_examples/style-guide/ts/systemjs.custom.js b/public/docs/_examples/style-guide/ts/systemjs.custom.js index bc5a4d2eb3..8181979346 100644 --- a/public/docs/_examples/style-guide/ts/systemjs.custom.js +++ b/public/docs/_examples/style-guide/ts/systemjs.custom.js @@ -2,19 +2,23 @@ // extra local packages var packageNames = [ '01-01', '01-01/app', '01-01/app/heroes', '01-01/app/heroes/shared', + '02-05', '02-05/app', '02-07', '02-07/app', '02-07/app/heroes', '02-07/app/users', '02-08', '02-08/app', '02-08/app/shared', - '03-01', '03-01/app', '03-01/app/shared', - '03-02', '03-02/app', '03-02/app/shared', - '03-03', '03-03/app', '03-03/app/shared', - '03-04', '03-04/app', '03-04/app/shared', - '03-05', '03-05/app', '03-05/app/shared', '03-05/app/shared/spinner', '03-05/app/shared/toast', + '03-01', '03-01/app', '03-01/app/core', + '03-02', '03-02/app', '03-02/app/core', + '03-03', '03-03/app', '03-03/app/core', + '03-04', '03-04/app', '03-04/app/core', + '03-05', '03-05/app', '03-05/app/core', '03-05/app/core/spinner', '03-05/app/core/toast', '03-05/app/heroes', '03-05/app/heroes/shared', - '03-06', '03-06/app', '03-06/app/shared', '03-06/app/shared/spinner', '03-06/app/shared/toast', + '03-06', '03-06/app', '03-06/app/core', '03-06/app/core/spinner', '03-06/app/core/toast', '03-06/app/heroes', '03-06/app/heroes/shared', + '04-08', '04-08/app', '04-08/app/heroes', '04-10', '04-10/app', '04-10/app/shared', '04-10/app/heroes', '04-10/app/shared/spinner', '04-10/app/shared/toast', - '04-10/app/shared/filter-text', '04-10/app/shared/modal', '04-10/app/shared/nav', - '04-14', '04-14/app', '04-14/app/heroes', '04-14/app/heroes/shared', '04-14/app/shared', + '04-10/app/shared/filter-text', + '04-11', '04-11/app', '04-11/app/core', '04-11/app/heroes', '04-11/app/core/spinner', + '04-11/app/core/nav', + '04-12', '04-12/app', '04-12/app/core', '04-12/app/heroes', '04-12/app/core/nav', '05-02', '05-02/app', '05-02/app/heroes', '05-02/app/heroes/shared', '05-02/app/heroes/shared/hero-button', '05-03', '05-03/app', '05-03/app/heroes', '05-03/app/heroes/shared', '05-03/app/heroes/shared/hero-button', '05-04', '05-04/app', '05-04/app/heroes', '05-04/app/heroes/shared', diff --git a/public/docs/_examples/template-syntax/dart/pubspec.yaml b/public/docs/_examples/template-syntax/dart/pubspec.yaml index 65bea5b496..f53eb65de1 100644 --- a/public/docs/_examples/template-syntax/dart/pubspec.yaml +++ b/public/docs/_examples/template-syntax/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: template_syntax description: Template Syntax version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/toh-1/dart/pubspec.yaml b/public/docs/_examples/toh-1/dart/pubspec.yaml index c4826c3511..4cd2834c35 100644 --- a/public/docs/_examples/toh-1/dart/pubspec.yaml +++ b/public/docs/_examples/toh-1/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: angular2_tour_of_heroes description: Tour of Heroes version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/toh-1/dart/web/index.html b/public/docs/_examples/toh-1/dart/web/index.html index 3c09e8af9d..3a2280f3b7 100644 --- a/public/docs/_examples/toh-1/dart/web/index.html +++ b/public/docs/_examples/toh-1/dart/web/index.html @@ -1,7 +1,7 @@ - Angular 2 Tour of Heroes + Angular Tour of Heroes diff --git a/public/docs/_examples/toh-2/dart/pubspec.yaml b/public/docs/_examples/toh-2/dart/pubspec.yaml index c4826c3511..4cd2834c35 100644 --- a/public/docs/_examples/toh-2/dart/pubspec.yaml +++ b/public/docs/_examples/toh-2/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: angular2_tour_of_heroes description: Tour of Heroes version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/toh-2/dart/web/index.html b/public/docs/_examples/toh-2/dart/web/index.html index 3c09e8af9d..3a2280f3b7 100644 --- a/public/docs/_examples/toh-2/dart/web/index.html +++ b/public/docs/_examples/toh-2/dart/web/index.html @@ -1,7 +1,7 @@ - Angular 2 Tour of Heroes + Angular Tour of Heroes diff --git a/public/docs/_examples/toh-3/dart/pubspec.yaml b/public/docs/_examples/toh-3/dart/pubspec.yaml index c4826c3511..4cd2834c35 100644 --- a/public/docs/_examples/toh-3/dart/pubspec.yaml +++ b/public/docs/_examples/toh-3/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: angular2_tour_of_heroes description: Tour of Heroes version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/toh-3/dart/web/index.html b/public/docs/_examples/toh-3/dart/web/index.html index 3c09e8af9d..3a2280f3b7 100644 --- a/public/docs/_examples/toh-3/dart/web/index.html +++ b/public/docs/_examples/toh-3/dart/web/index.html @@ -1,7 +1,7 @@ - Angular 2 Tour of Heroes + Angular Tour of Heroes diff --git a/public/docs/_examples/toh-4/dart/pubspec.yaml b/public/docs/_examples/toh-4/dart/pubspec.yaml index c4826c3511..4cd2834c35 100644 --- a/public/docs/_examples/toh-4/dart/pubspec.yaml +++ b/public/docs/_examples/toh-4/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: angular2_tour_of_heroes description: Tour of Heroes version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/toh-4/dart/web/index.html b/public/docs/_examples/toh-4/dart/web/index.html index 3c09e8af9d..3a2280f3b7 100644 --- a/public/docs/_examples/toh-4/dart/web/index.html +++ b/public/docs/_examples/toh-4/dart/web/index.html @@ -1,7 +1,7 @@ - Angular 2 Tour of Heroes + Angular Tour of Heroes diff --git a/public/docs/_examples/toh-5/dart/pubspec.yaml b/public/docs/_examples/toh-5/dart/pubspec.yaml index c4826c3511..4cd2834c35 100644 --- a/public/docs/_examples/toh-5/dart/pubspec.yaml +++ b/public/docs/_examples/toh-5/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: angular2_tour_of_heroes description: Tour of Heroes version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/_examples/toh-5/dart/web/index.html b/public/docs/_examples/toh-5/dart/web/index.html index be9b1b4ca2..3be150d2a2 100644 --- a/public/docs/_examples/toh-5/dart/web/index.html +++ b/public/docs/_examples/toh-5/dart/web/index.html @@ -7,7 +7,7 @@ - Angular 2 Tour of Heroes + Angular Tour of Heroes diff --git a/public/docs/_examples/toh-6/dart/pubspec.yaml b/public/docs/_examples/toh-6/dart/pubspec.yaml index 653f7ec2f4..2c43d9deae 100644 --- a/public/docs/_examples/toh-6/dart/pubspec.yaml +++ b/public/docs/_examples/toh-6/dart/pubspec.yaml @@ -4,10 +4,10 @@ name: angular2_tour_of_heroes description: Tour of Heroes version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' # #docregion additions dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 # #enddocregion additions browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 diff --git a/public/docs/_examples/toh-6/dart/web/index.html b/public/docs/_examples/toh-6/dart/web/index.html index acb7482f70..135bbe1091 100644 --- a/public/docs/_examples/toh-6/dart/web/index.html +++ b/public/docs/_examples/toh-6/dart/web/index.html @@ -3,7 +3,7 @@ - Angular 2 Tour of Heroes + Angular Tour of Heroes diff --git a/public/docs/_examples/toh-6/ts/app/hero.service.ts b/public/docs/_examples/toh-6/ts/app/hero.service.ts index e220982f6f..49c760073e 100644 --- a/public/docs/_examples/toh-6/ts/app/hero.service.ts +++ b/public/docs/_examples/toh-6/ts/app/hero.service.ts @@ -42,7 +42,7 @@ export class HeroService { // #docregion delete delete(id: number): Promise { - let url = `${this.heroesUrl}/${id}`; + const url = `${this.heroesUrl}/${id}`; return this.http.delete(url, {headers: this.headers}) .toPromise() .then(() => null) diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts index b4926d8c69..6ac76407b1 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts @@ -1,18 +1,29 @@ declare var angular: any; +// #docregion ngmodule +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +@NgModule({ + imports: [ BrowserModule ] +}) +export class AppModule {} +// #enddocregion ngmodule +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); + // #docregion bootstrap import { UpgradeAdapter } from '@angular/upgrade'; // #enddocregion bootstrap -angular.module('heroApp', []) - .controller('MainCtrl', function() { - this.message = 'Hello world'; - }); +// This blank is expected to trigger the docplaster // #docregion bootstrap -const upgradeAdapter = new UpgradeAdapter(); +const upgradeAdapter = new UpgradeAdapter(AppModule); upgradeAdapter.bootstrap(document.body, ['heroApp'], {strictDi: true}); // #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/upgrade_adapter.ts index f6066f9109..6ccaa31b9c 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/upgrade_adapter.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/upgrade_adapter.ts @@ -1,3 +1,16 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +@NgModule({ + imports: [ BrowserModule ] +}) +export class AppModule {} + +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); + // #docregion import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); +export const upgradeAdapter = new UpgradeAdapter(AppModule); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/app.module.ts index ad48568e09..5daeb671e3 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/app.module.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/app.module.ts @@ -1,10 +1,18 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; import { UpgradeAdapter } from '@angular/upgrade'; import { MainController } from './main.controller'; import { HeroDetailComponent } from './hero-detail.component'; +@NgModule({ + imports: [ BrowserModule ], + declarations: [ HeroDetailComponent ] +}) +export class AppModule {} + declare var angular: any; -const upgradeAdapter = new UpgradeAdapter(); +const upgradeAdapter = new UpgradeAdapter(AppModule); angular.module('heroApp', []) .controller('MainController', MainController) diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/upgrade_adapter.ts index f6066f9109..c98ab182a8 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/upgrade_adapter.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/upgrade_adapter.ts @@ -1,3 +1,19 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { HeroDetailComponent } from './hero-detail.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ HeroDetailComponent ] +}) +export class AppModule {} + +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); + // #docregion import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); +export const upgradeAdapter = new UpgradeAdapter(AppModule); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/app.module.ts index 9ab3f70e94..16b77819c5 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/app.module.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/app.module.ts @@ -5,8 +5,6 @@ import { upgradeAdapter } from './upgrade_adapter'; declare var angular: any; // #docregion register -upgradeAdapter.addProvider(Heroes); - angular.module('heroApp', []) .factory('heroes', upgradeAdapter.downgradeNg2Provider(Heroes)) .component('heroDetail', heroDetailComponent); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts index f6066f9109..d99d587f0f 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts @@ -1,3 +1,19 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #docregion ngmodule +import { Heroes } from './heroes'; + +@NgModule({ + imports: [ BrowserModule ], + providers: [ Heroes ] +}) +export class AppModule {} +// #enddocregion ngmodule +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); + // #docregion import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); +export const upgradeAdapter = new UpgradeAdapter(AppModule); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/container.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/container.component.ts index a468898e5f..1b740d6554 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/container.component.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/container.component.ts @@ -1,10 +1,7 @@ // #docregion import { Component } from '@angular/core'; -import { upgradeAdapter } from './upgrade_adapter'; import { Hero } from '../hero'; -const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); - @Component({ selector: 'my-container', template: ` @@ -12,8 +9,7 @@ const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail');

{{hero.description}}

- `, - directives: [HeroDetail] + ` }) export class ContainerComponent { hero = new Hero(1, 'Windstorm', 'Specific powers of controlling winds'); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/upgrade_adapter.ts index f6066f9109..b0f947c8e5 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/upgrade_adapter.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/upgrade_adapter.ts @@ -1,3 +1,20 @@ // #docregion import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); +import { NgModule, forwardRef } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { ContainerComponent } from './container.component'; + +export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule)); +const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ ContainerComponent, HeroDetail ] +}) +export class AppModule {} + +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/app.module.ts index d9af4e0104..a09db040d1 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/app.module.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/app.module.ts @@ -1,11 +1,21 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + import { MainController } from './main.controller'; // #docregion downgradecomponent import { HeroDetailComponent } from './hero-detail.component'; // #enddocregion downgradecomponent + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ HeroDetailComponent ] +}) +export class AppModule {} + import { UpgradeAdapter } from '@angular/upgrade'; -const upgradeAdapter = new UpgradeAdapter(); +const upgradeAdapter = new UpgradeAdapter(AppModule); // #docregion downgradecomponent diff --git a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/app.module.ts index 44935340f0..d5f173b5b5 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/app.module.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/app.module.ts @@ -1,10 +1,19 @@ -// #docregion downgradecomponent +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +// #docregion downgradecomponent, ngmodule import { HeroDetailComponent } from './hero-detail.component'; // #enddocregion downgradecomponent +@NgModule({ + imports: [ BrowserModule ], + declarations: [ HeroDetailComponent ] +}) +export class AppModule {} +// #enddocregion ngmodule import { UpgradeAdapter } from '@angular/upgrade'; -const upgradeAdapter = new UpgradeAdapter(); +const upgradeAdapter = new UpgradeAdapter(AppModule); // #docregion downgradecomponent diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/container.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/container.component.ts index 0055370ea8..8d76085174 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/container.component.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/container.component.ts @@ -1,10 +1,7 @@ // #docregion import { Component } from '@angular/core'; -import { upgradeAdapter } from './upgrade_adapter'; import { Hero } from '../hero'; -const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); - @Component({ selector: 'my-container', template: ` @@ -12,8 +9,7 @@ const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); - `, - directives: [HeroDetail] + ` }) export class ContainerComponent { hero = new Hero(1, 'Windstorm'); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/upgrade_adapter.ts index f6066f9109..b0f947c8e5 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/upgrade_adapter.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/upgrade_adapter.ts @@ -1,3 +1,20 @@ // #docregion import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); +import { NgModule, forwardRef } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { ContainerComponent } from './container.component'; + +export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule)); +const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ ContainerComponent, HeroDetail ] +}) +export class AppModule {} + +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/container.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/container.component.ts index ca8a93dd26..1e3ebf509b 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/container.component.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/container.component.ts @@ -1,16 +1,12 @@ // #docregion import { Component } from '@angular/core'; -import { upgradeAdapter } from './upgrade_adapter'; - -const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); @Component({ selector: 'my-container', template: `

Tour of Heroes

- `, - directives: [HeroDetail] + ` }) export class ContainerComponent { diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts index f6066f9109..c9173347bc 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts +++ b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts @@ -1,3 +1,23 @@ // #docregion import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); +import { NgModule, forwardRef } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { ContainerComponent } from './container.component'; + +export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule)); + +// #docregion heroupgrade +const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ ContainerComponent, HeroDetail ] +}) +export class AppModule {} +// #enddocregion heroupgrade + +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); diff --git a/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-bootstrap.html b/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-bootstrap.html index ff5481a40d..fc090c9eb9 100644 --- a/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-bootstrap.html +++ b/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-bootstrap.html @@ -16,9 +16,6 @@ - - - - - - - - - - - + diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js index 31589119d2..19fcc89fe9 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js @@ -1,21 +1,25 @@ // #docregion // /*global jasmine, __karma__, window*/ -Error.stackTraceLimit = Infinity; +Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing. + +// Uncomment to get full stacktrace output. Sometimes helpful, usually not. +// Error.stackTraceLimit = Infinity; // + jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; -__karma__.loaded = function () { -}; +var builtPath = '/base/app/'; + +__karma__.loaded = function () { }; function isJsFile(path) { return path.slice(-3) == '.js'; } function isSpecFile(path) { - return /\.spec\.js$/.test(path); + return /\.spec\.(.*\.)?js$/.test(path); } function isBuiltFile(path) { - var builtPath = '/base/app/'; return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath); } @@ -25,27 +29,61 @@ var allSpecFiles = Object.keys(window.__karma__.files) System.config({ baseURL: '/base', - packageWithIndex: true // sadly, we can't use umd packages (yet?) + // Extend usual application package list with test folder + packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } }, + + // Assume npm: is set in `paths` in systemjs.config + // Map the angular testing umd bundles + map: { + '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', + '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', + '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js', + '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js', + '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js', + '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js', + '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js', + '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js', + }, }); System.import('systemjs.config.js') - .then(() => Promise.all([ - System.import('@angular/core/testing'), - System.import('@angular/platform-browser-dynamic/testing') - ])) - .then((providers) => { - var coreTesting = providers[0]; + .then(importSystemJsExtras) + .then(initTestBed) + .then(initTesting); + +/** Optional SystemJS configuration extras. Keep going w/o it */ +function importSystemJsExtras(){ + return System.import('systemjs.config.extras.js') + .catch(function(reason) { + console.log( + 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.' + ); + console.log(reason); + }); +} + +function initTestBed(){ + return Promise.all([ + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') + ]) + + .then(function (providers) { + var coreTesting = providers[0]; var browserTesting = providers[1]; + coreTesting.TestBed.initTestEnvironment( browserTesting.BrowserDynamicTestingModule, browserTesting.platformBrowserDynamicTesting()); }) - .then(function () { - // Finally, load all spec files. - // This will run the tests directly. - return Promise.all( - allSpecFiles.map(function (moduleName) { - return System.import(moduleName); - })); - }) +} + +// Import all spec files and start karma +function initTesting () { + return Promise.all( + allSpecFiles.map(function (moduleName) { + return System.import(moduleName); + }) + ) .then(__karma__.start, __karma__.error); +} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js index 48cc490f89..3decfbdd3e 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js @@ -63,11 +63,10 @@ module.exports = function(config) { frameworks: ['jasmine'], - browsers: ['Chrome', 'Firefox'], + browsers: ['Chrome'], plugins: [ 'karma-chrome-launcher', - 'karma-firefox-launcher', 'karma-jasmine' ] diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js index a54f8bb20c..18b947dbb5 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js @@ -1,59 +1,47 @@ /** - * System configuration for Angular 2 samples + * System configuration for Angular samples * Adjust as necessary for your application needs. */ -(function(global) { - - // map tells the System loader where to look for things +(function (global) { // #docregion paths - var map = { - 'app': '/app', // 'dist', - - '@angular': '/node_modules/@angular', - 'angular-in-memory-web-api': '/node_modules/angular-in-memory-web-api', - 'rxjs': '/node_modules/rxjs' - }; - - var packages = { - '/app': { main: 'main.js', defaultExtension: 'js' }, - 'rxjs': { defaultExtension: 'js' }, - 'angular-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, - }; - // #enddocregion paths - - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'forms', - 'http', - 'platform-browser', - 'platform-browser-dynamic', - 'router', - 'router-deprecated', - 'upgrade', - ]; - - // Individual files (~300 requests): - function packIndex(pkgName) { - packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - } - - // Bundled (~40 requests): - function packUmd(pkgName) { - packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' }; - } - - var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; - - // Add package entries for angular packages - ngPackageNames.forEach(setPackageConfig); - - var config = { - map: map, - packages: packages - } - - System.config(config); + System.config({ + paths: { + // paths serve as alias + 'npm:': '/node_modules/' + }, + map: { + app: '/app', + // #enddocregion paths + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api', + // #docregion paths + }, + // #enddocregion paths + // packages tells the System loader how to load when no filename and/or no extension + packages: { + 'app': { + main: './main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + }, + 'angular-in-memory-web-api': { + main: './index.js', + defaultExtension: 'js' + } + } + }); })(this); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/e2e-spec.ts.disabled b/public/docs/_examples/upgrade-phonecat-3-final/e2e-spec.ts similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/e2e-spec.ts.disabled rename to public/docs/_examples/upgrade-phonecat-3-final/e2e-spec.ts diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app-routing.module.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app-routing.module.ts new file mode 100644 index 0000000000..16a72b069e --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app-routing.module.ts @@ -0,0 +1,23 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { APP_BASE_HREF, HashLocationStrategy, LocationStrategy } from '@angular/common'; + +import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; +import { PhoneListComponent } from './phone-list/phone-list.component'; + +const routes: Routes = [ + { path: '', redirectTo: 'phones', pathMatch: 'full' }, + { path: 'phones', component: PhoneListComponent }, + { path: 'phones/:phoneId', component: PhoneDetailComponent } +]; + +@NgModule({ + imports: [ RouterModule.forRoot(routes) ], + exports: [ RouterModule ], + providers: [ + { provide: APP_BASE_HREF, useValue: '!' }, + { provide: LocationStrategy, useClass: HashLocationStrategy }, + ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.component.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.component.ts index af4e91c80f..fa4e5f7f4b 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.component.ts +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.component.ts @@ -1,18 +1,9 @@ // #docregion import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated'; -import { PhoneListComponent } from './phone-list/phone-list.component'; -import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; -@RouteConfig([ - {path: '/phones', name: 'Phones', component: PhoneListComponent}, - {path: '/phones/:phoneId', name: 'Phone', component: PhoneDetailComponent}, - {path: '/', redirectTo: ['Phones']} -]) @Component({ selector: 'phonecat-app', - template: '', - directives: [ROUTER_DIRECTIVES] + template: '' }) export class AppComponent { } diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.module.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.module.ts new file mode 100644 index 0000000000..58acb5bce3 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.module.ts @@ -0,0 +1,34 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { CheckmarkPipe } from './core/checkmark/checkmark.pipe'; +import { Phone } from './core/phone/phone.service'; +import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; +import { PhoneListComponent } from './phone-list/phone-list.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + AppRoutingModule + ], + declarations: [ + AppComponent, + PhoneListComponent, + CheckmarkPipe, + PhoneDetailComponent + ], + providers: [ + Phone, + ], + // #docregion bootstrap + bootstrap: [ AppComponent ] + // #enddocregion bootstrap +}) +export class AppModule {} diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts index b3a1c59a8d..75150500a6 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts @@ -1,21 +1,10 @@ -import { - describe, - beforeEachProviders, - it, - inject, - expect -} from '@angular/core/testing'; import { CheckmarkPipe } from './checkmark.pipe'; describe('CheckmarkPipe', function() { - beforeEachProviders(() => [CheckmarkPipe]); - - it('should convert boolean values to unicode checkmark or cross', - inject([CheckmarkPipe], function(checkmarkPipe: CheckmarkPipe) { - expect(checkmarkPipe.transform(true)).toBe('\u2713'); - expect(checkmarkPipe.transform(false)).toBe('\u2718'); - }) - ); - + it('should convert boolean values to unicode checkmark or cross', function () { + const checkmarkPipe = new CheckmarkPipe(); + expect(checkmarkPipe.transform(true)).toBe('\u2713'); + expect(checkmarkPipe.transform(false)).toBe('\u2718'); + }); }); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts index c9f511913b..e3a422965b 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts @@ -1,10 +1,4 @@ -import { - describe, - beforeEach, - beforeEachProviders, - it, - inject -} from '@angular/core/testing'; +import { inject, TestBed } from '@angular/core/testing'; import { Http, BaseRequestOptions, @@ -23,15 +17,19 @@ describe('Phone', function() { ]; let mockBackend: MockBackend; - beforeEachProviders(() => [ - Phone, - MockBackend, - BaseRequestOptions, - { provide: Http, - useFactory: (backend: MockBackend, options: BaseRequestOptions) => new Http(backend, options), - deps: [MockBackend, BaseRequestOptions] - } - ]); + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + Phone, + MockBackend, + BaseRequestOptions, + { provide: Http, + useFactory: (backend: MockBackend, options: BaseRequestOptions) => new Http(backend, options), + deps: [MockBackend, BaseRequestOptions] + } + ] + }); + }); beforeEach(inject([MockBackend, Phone], (_mockBackend_: MockBackend, _phone_: Phone) => { mockBackend = _mockBackend_; diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-venue.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-venue.0.jpg new file mode 100644 index 0000000000..b4cb4eb25f Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-venue.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/droid-2-global-by-motorola.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/droid-2-global-by-motorola.0.jpg new file mode 100644 index 0000000000..60700a2ab3 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/droid-2-global-by-motorola.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/droid-pro-by-motorola.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/droid-pro-by-motorola.0.jpg new file mode 100644 index 0000000000..c7710de986 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/droid-pro-by-motorola.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/lg-axis.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/lg-axis.0.jpg new file mode 100644 index 0000000000..55e5a23bb2 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/lg-axis.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg new file mode 100644 index 0000000000..e452ae7e7c Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg new file mode 100644 index 0000000000..21e4b8d741 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg new file mode 100644 index 0000000000..c7c5e3ba0c Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-galaxy-tab.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-galaxy-tab.0.jpg new file mode 100644 index 0000000000..3750377ad9 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-galaxy-tab.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-gem.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-gem.0.jpg new file mode 100644 index 0000000000..0d5024a026 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-gem.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg new file mode 100644 index 0000000000..11b8f860cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg new file mode 100644 index 0000000000..11b8f860cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-transform.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-transform.0.jpg new file mode 100644 index 0000000000..0e3107caf5 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/samsung-transform.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/sanyo-zio.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/sanyo-zio.0.jpg new file mode 100644 index 0000000000..9eeb9b96ed Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/sanyo-zio.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/t-mobile-g2.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/t-mobile-g2.0.jpg new file mode 100644 index 0000000000..6b6c09e058 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/t-mobile-g2.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg new file mode 100644 index 0000000000..beba1f6827 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/main.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/main.ts index 4db648092b..08be7a99ba 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/main.ts +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/main.ts @@ -1,27 +1,10 @@ // #docregion // #docregion imports -import { - LocationStrategy, - HashLocationStrategy, - APP_BASE_HREF -} from '@angular/common'; -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { FormsModule } from '@angular/forms'; -import { HTTP_PROVIDERS } from '@angular/http'; -import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; -import { Phone } from './core/phone/phone.service'; -import { AppComponent } from './app.component'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app.module'; // #enddocregion imports // #docregion bootstrap -bootstrap(AppComponent, { - imports: [FormsModule], - providers: [ - HTTP_PROVIDERS, - ROUTER_PROVIDERS, - { provide: APP_BASE_HREF, useValue: '!' }, - { provide: LocationStrategy, useClass: HashLocationStrategy }, - Phone - ] -}); +platformBrowserDynamic().bootstrapModule(AppModule); // #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts index 79b3cddcfb..e3b9143a94 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts @@ -1,25 +1,15 @@ // #docregion -import { HTTP_PROVIDERS } from '@angular/http'; -// #docregion routeparams -import { RouteParams } from '@angular/router-deprecated'; +// #docregion activatedroute +import { ActivatedRoute } from '@angular/router'; -// #enddocregion routeparams +// #enddocregion activatedroute import { Observable } from 'rxjs/Rx'; -import { - describe, - beforeEachProviders, - inject, - it, - expect -} from '@angular/core/testing'; -import { - TestComponentBuilder, - ComponentFixture -} from '@angular/compiler/testing'; +import { async, TestBed } from '@angular/core/testing'; import { PhoneDetailComponent } from './phone-detail.component'; import { Phone, PhoneData } from '../core/phone/phone.service'; +import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; function xyzPhoneData(): PhoneData { return { @@ -29,31 +19,41 @@ function xyzPhoneData(): PhoneData { }; } -class MockPhone extends Phone { +class MockPhone { get(id: string): Observable { return Observable.of(xyzPhoneData()); } } +// #docregion activatedroute + +class ActivatedRouteMock { + constructor(public snapshot: any) {} +} + +// #enddocregion activatedroute + describe('PhoneDetailComponent', () => { - // #docregion routeparams + // #docregion activatedroute - beforeEachProviders(() => [ - { provide: Phone, useClass: MockPhone }, - { provide: RouteParams, useValue: new RouteParams({phoneId: 'xyz'})}, - HTTP_PROVIDERS - ]); - // #enddocregion routeparams - - it('should fetch phone detail', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(PhoneDetailComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1')).toHaveText(xyzPhoneData().name); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CheckmarkPipe, PhoneDetailComponent ], + providers: [ + { provide: Phone, useClass: MockPhone }, + { provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) } + ] + }) + .compileComponents(); })); + // #enddocregion activatedroute + + it('should fetch phone detail', () => { + const fixture = TestBed.createComponent(PhoneDetailComponent); + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name); + }); }); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.ts index 7d42e20dee..ceba9a6f70 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.ts +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.ts @@ -1,25 +1,25 @@ // #docplaster // #docregion -import { Component } from '@angular/core'; -import { RouteParams } from '@angular/router-deprecated'; +import { Component } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + import { Phone, PhoneData } from '../core/phone/phone.service'; -import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; @Component({ moduleId: module.id, selector: 'phone-detail', - templateUrl: 'phone-detail.template.html', - pipes: [ CheckmarkPipe ] + templateUrl: 'phone-detail.template.html' }) export class PhoneDetailComponent { phone: PhoneData; mainImageUrl: string; - constructor(routeParams: RouteParams, phone: Phone) { - phone.get(routeParams.get('phoneId')).subscribe(phone => { - this.phone = phone; - this.setImage(phone.images[0]); - }); + constructor(activatedRoute: ActivatedRoute, phone: Phone) { + phone.get(activatedRoute.snapshot.params['phoneId']) + .subscribe((p: PhoneData) => { + this.phone = p; + this.setImage(p.images[0]); + }); } setImage(imageUrl: string) { diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts index 3d6cd93b15..834c93df8f 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts @@ -1,42 +1,21 @@ /* tslint:disable */ // #docregion routestuff -import { Directive } from '@angular/core'; -import { HTTP_PROVIDERS } from '@angular/http'; -import { - Router, - RouterLink, - RootRouter, - RouteRegistry, - ROUTER_PRIMARY_COMPONENT -} from '@angular/router-deprecated'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs/Rx'; -import { - describe, - addProviders, - inject, - it, - expect, - // MockApplicationRef -} from '@angular/core/testing'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SpyLocation } from '@angular/common/testing'; -import { - TestComponentBuilder, - ComponentFixture -} from '@angular/core/testing'; -import { AppComponent } from '../app.component'; import { PhoneListComponent } from './phone-list.component'; import { Phone, PhoneData } from '../core/phone/phone.service'; // #enddocregion routestuff -@Directive({ - selector: '[routerLink]', - inputs: ['routeParams: routerLink', 'target: target'] -}) -class RouterLinkMock {} +class ActivatedRouteMock { + constructor(public snapshot: any) {} +} -class MockPhone extends Phone { +class MockPhone { query(): Observable { return Observable.of([ {name: 'Nexus S', snippet: '', images: []}, @@ -45,52 +24,48 @@ class MockPhone extends Phone { } } +let fixture: ComponentFixture; + describe('PhoneList', () => { // #docregion routestuff - addProviders([ - RouteRegistry, - { provide: Router, useClass: RootRouter }, - { provide: ROUTER_PRIMARY_COMPONENT, useValue: AppComponent }, - { provide: Location, useClass: SpyLocation}, - { provide: Phone, useClass: MockPhone}, - HTTP_PROVIDERS - ]); + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PhoneListComponent ], + providers: [ + { provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) }, + { provide: Location, useClass: SpyLocation }, + { provide: Phone, useClass: MockPhone }, + ], + schemas: [ NO_ERRORS_SCHEMA ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PhoneListComponent); + }); // #enddocregion routestuff - it('should create "phones" model with 2 phones fetched from xhr', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .overrideDirective(AppComponent, RouterLink, RouterLinkMock) - .overrideDirective(PhoneListComponent, RouterLink, RouterLinkMock) - .createAsync(PhoneListComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); - expect( - compiled.querySelector('.phone-list-item:nth-child(1)').textContent - ).toContain('Motorola DROID'); - expect( - compiled.querySelector('.phone-list-item:nth-child(2)').textContent - ).toContain('Nexus S'); - }); - })); + it('should create "phones" model with 2 phones fetched from xhr', () => { + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); + expect( + compiled.querySelector('.phone-list-item:nth-child(1)').textContent + ).toContain('Motorola DROID'); + expect( + compiled.querySelector('.phone-list-item:nth-child(2)').textContent + ).toContain('Nexus S'); + }); - it('should set the default value of orderProp model', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb - .overrideDirective(AppComponent, RouterLink, RouterLinkMock) - .overrideDirective(PhoneListComponent, RouterLink, RouterLinkMock) - .createAsync(PhoneListComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect( - compiled.querySelector('select option:last-child').selected - ).toBe(true); - }); - })); + xit('should set the default value of orderProp model', () => { + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect( + compiled.querySelector('select option:last-child').selected + ).toBe(true); + }); }); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.ts index e97e740415..abbe27c5f2 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.ts +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.ts @@ -1,14 +1,13 @@ // #docplaster // #docregion top import { Component } from '@angular/core'; -import { RouterLink } from '@angular/router-deprecated'; + import { Phone, PhoneData } from '../core/phone/phone.service'; @Component({ moduleId: module.id, selector: 'phone-list', templateUrl: 'phone-list.template.html', - directives: [ RouterLink ] }) // #enddocregion top export class PhoneListComponent { @@ -41,20 +40,20 @@ export class PhoneListComponent { } private sortPhones(phones: PhoneData[]) { - if (phones && this.orderProp) { - return phones - .slice(0) // Make a copy - .sort((a, b) => { - if (a[this.orderProp] < b[this.orderProp]) { - return -1; - } else if ([b[this.orderProp] < a[this.orderProp]]) { - return 1; - } else { - return 0; - } - }); - } - return phones; + if (phones && this.orderProp) { + return phones + .slice(0) // Make a copy + .sort((a, b) => { + if (a[this.orderProp] < b[this.orderProp]) { + return -1; + } else if ([b[this.orderProp] < a[this.orderProp]]) { + return 1; + } else { + return 0; + } + }); + } + return phones; } // #enddocregion getphones // #docregion initialclass diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.template.html b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.template.html index 9846664768..b4a994b297 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.template.html +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.template.html @@ -26,10 +26,10 @@ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js b/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js index 48cc490f89..3decfbdd3e 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js @@ -63,11 +63,10 @@ module.exports = function(config) { frameworks: ['jasmine'], - browsers: ['Chrome', 'Firefox'], + browsers: ['Chrome'], plugins: [ 'karma-chrome-launcher', - 'karma-firefox-launcher', 'karma-jasmine' ] diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/systemjs.config.1.js b/public/docs/_examples/upgrade-phonecat-3-final/ts/systemjs.config.1.js index a54f8bb20c..592029cd65 100644 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/systemjs.config.1.js +++ b/public/docs/_examples/upgrade-phonecat-3-final/ts/systemjs.config.1.js @@ -1,59 +1,47 @@ /** - * System configuration for Angular 2 samples + * System configuration for Angular samples * Adjust as necessary for your application needs. */ -(function(global) { - - // map tells the System loader where to look for things +(function (global) { // #docregion paths - var map = { - 'app': '/app', // 'dist', - - '@angular': '/node_modules/@angular', - 'angular-in-memory-web-api': '/node_modules/angular-in-memory-web-api', - 'rxjs': '/node_modules/rxjs' - }; - - var packages = { - '/app': { main: 'main.js', defaultExtension: 'js' }, - 'rxjs': { defaultExtension: 'js' }, - 'angular-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, - }; - // #enddocregion paths - - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'forms', - 'http', - 'platform-browser', - 'platform-browser-dynamic', - 'router', - 'router-deprecated', - 'upgrade', - ]; - - // Individual files (~300 requests): - function packIndex(pkgName) { - packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - } - - // Bundled (~40 requests): - function packUmd(pkgName) { - packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' }; - } - - var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; - - // Add package entries for angular packages - ngPackageNames.forEach(setPackageConfig); - - var config = { - map: map, - packages: packages - } - - System.config(config); + System.config({ + paths: { + // paths serve as alias + 'npm:': '/node_modules/' + }, + map: { + app: '/app', + // #enddocregion paths + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api', + // #docregion paths + }, + // #enddocregion paths + // packages tells the System loader how to load when no filename and/or no extension + packages: { + 'app': { + main: './main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + }, + 'angular-in-memory-web-api': { + main: './index.js', + defaultExtension: 'js' + } + } + }); })(this); diff --git a/public/docs/_examples/user-input/dart/pubspec.yaml b/public/docs/_examples/user-input/dart/pubspec.yaml index a75460f74f..3d885ba12d 100644 --- a/public/docs/_examples/user-input/dart/pubspec.yaml +++ b/public/docs/_examples/user-input/dart/pubspec.yaml @@ -3,9 +3,9 @@ name: user_input description: User input example version: 0.0.1 environment: - sdk: '>=1.13.0 <2.0.0' + sdk: '>=1.19.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.21 + angular2: 2.0.0-beta.22 browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: diff --git a/public/docs/dart/latest/_data.json b/public/docs/dart/latest/_data.json index c23053213e..00b82e86a2 100644 --- a/public/docs/dart/latest/_data.json +++ b/public/docs/dart/latest/_data.json @@ -4,7 +4,7 @@ "title": "Angular Docs", "subtitle": "Dart", "menuTitle": "Docs Home", - "banner": "Angular release is beta.21. View the change log to see enhancements, fixes, and breaking changes." + "banner": "Angular release is beta.22. View the change log to see enhancements, fixes, and breaking changes." }, "quickstart": { diff --git a/public/docs/dart/latest/cookbook/_data.json b/public/docs/dart/latest/cookbook/_data.json index f0c0dad0d4..e12d383b14 100644 --- a/public/docs/dart/latest/cookbook/_data.json +++ b/public/docs/dart/latest/cookbook/_data.json @@ -47,6 +47,12 @@ "hide": true }, + "i18n": { + "title": "Internationalization (i18n)", + "intro": "Translate the app's template text into multiple languages", + "hide": true + }, + "rc4-to-rc5": { "title": "RC4 to RC5 Migration", "intro": "Migrate your RC4 app to RC5 in minutes.", diff --git a/public/docs/dart/latest/cookbook/i18n.jade b/public/docs/dart/latest/cookbook/i18n.jade new file mode 100644 index 0000000000..c743361ac8 --- /dev/null +++ b/public/docs/dart/latest/cookbook/i18n.jade @@ -0,0 +1 @@ +include ../../../_includes/_ts-temp diff --git a/public/docs/dart/latest/guide/i18n.jade b/public/docs/dart/latest/guide/i18n.jade new file mode 100644 index 0000000000..6778b6af28 --- /dev/null +++ b/public/docs/dart/latest/guide/i18n.jade @@ -0,0 +1 @@ +!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/dart/latest/quickstart.jade b/public/docs/dart/latest/quickstart.jade index 3d48f658b9..ee8ea0e87a 100644 --- a/public/docs/dart/latest/quickstart.jade +++ b/public/docs/dart/latest/quickstart.jade @@ -30,7 +30,7 @@ block package-and-config-files 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). - Angular 2 is still changing, so provide an exact version: **2.0.0-beta.21**. + Angular 2 is still changing, so provide an exact version: **2.0.0-beta.22**. [pubspec]: https://www.dartlang.org/tools/pub/pubspec.html @@ -79,7 +79,7 @@ block run-app block build-app .alert.is-important :marked - If you don't see **My First Angular 2 App**, make sure you've entered all the code correctly, + If you don't see **My First Angular App**, make sure you've entered all the code correctly, in the [proper folders](#wrap-up), and run `pub get`. diff --git a/public/docs/js/latest/cookbook/_data.json b/public/docs/js/latest/cookbook/_data.json index a5e0ca3011..5660152bd5 100644 --- a/public/docs/js/latest/cookbook/_data.json +++ b/public/docs/js/latest/cookbook/_data.json @@ -42,6 +42,12 @@ "intro": "Validate user's form entries" }, + "i18n": { + "title": "Internationalization (i18n)", + "intro": "Translate the app's template text into multiple languages", + "hide": true + }, + "rc4-to-rc5": { "title": "RC4 to RC5 Migration", "intro": "Migrate your RC4 app to RC5 in minutes.", diff --git a/public/docs/js/latest/cookbook/i18n.jade b/public/docs/js/latest/cookbook/i18n.jade new file mode 100644 index 0000000000..c743361ac8 --- /dev/null +++ b/public/docs/js/latest/cookbook/i18n.jade @@ -0,0 +1 @@ +include ../../../_includes/_ts-temp diff --git a/public/docs/js/latest/guide/i18n.jade b/public/docs/js/latest/guide/i18n.jade new file mode 100644 index 0000000000..6778b6af28 --- /dev/null +++ b/public/docs/js/latest/guide/i18n.jade @@ -0,0 +1 @@ +!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/ts/_cache/quickstart.jade b/public/docs/ts/_cache/quickstart.jade index 1e01b8f64d..95faaf7a84 100644 --- a/public/docs/ts/_cache/quickstart.jade +++ b/public/docs/ts/_cache/quickstart.jade @@ -290,7 +290,7 @@ p. The **template** specifies the component's companion template, written in an enhanced form of HTML that tells Angular how to render this component's view. - >Our template is a single line of HTML announcing "*My First Angular 2 App*". + >Our template is a single line of HTML announcing "*My First Angular App*". >A more advanced template could contain data bindings to component properties and might identify other application components which have their own templates. @@ -556,7 +556,7 @@ block build-app :marked ## Make some changes - Try changing the message to "My SECOND Angular 2 app". + Try changing the message to "My SECOND Angular app". block server-watching :marked The TypeScript compiler and `lite-server` are watching. diff --git a/public/docs/ts/latest/cookbook/_data.json b/public/docs/ts/latest/cookbook/_data.json index 3c17b79141..e73c977bd0 100644 --- a/public/docs/ts/latest/cookbook/_data.json +++ b/public/docs/ts/latest/cookbook/_data.json @@ -46,6 +46,11 @@ "intro": "验证用户在表单中的输入" }, + "i18n": { + "title": "国际化(i18n)", + "intro": "把应用的模板文本翻译成多种语言" + }, + "rc4-to-rc5": { "title": "如何从RC4迁移到RC5", "intro": "分分钟把RC4迁移到RC5" diff --git a/public/docs/ts/latest/cookbook/i18n.jade b/public/docs/ts/latest/cookbook/i18n.jade new file mode 100644 index 0000000000..8f58098f9d --- /dev/null +++ b/public/docs/ts/latest/cookbook/i18n.jade @@ -0,0 +1,350 @@ +include ../_util-fns + +:marked + Angular's _internationalization_ ("_i18n_") tools help make your app availble in multiple languages. + + + ## Table of contents + + * [Angular and i18n template translation](#angular-i18n) + * [Mark text with the _i18n_ attribute](#i18n-attribute) + * [Extract text with ng-xi18n](#ng-xi18n) + * [Translate](#translate) + * [Merge the translation file into the app](#merge) + * [JiT configuration](#jit) + * [AoT configuration](#aot) + +:marked + **Try this** live example of a JiT-compiled app, translated into French. + + +a#angular-i18n +.l-main-section +:marked + ## Angular and _i18n_ template translation + + Application internationalization is a challenging, many-faceted effort that + takes dedication and enduring commitment. + Angular's _i18n_ internationalization facilities can help. + + This page describes the _i18n_ tools to assist translation of component template text + into multiple languages. + +.l-sub-section + :marked + Practitioners of _internationalization_ refer to a translatable text as a "_message_". + This page uses the words "_text_" and "_message_" interchangably and in the combination, "_text message_". + +:marked + The _i18n_ template translation process has four phases: + + 1. Mark static text messages in your component templates for translation. + + 1. An angular _i18n_ tool extracts the marked messages into an industry standard translation source file. + + 1. A translator edits that file, translating the extracted text messages into the target language, + and returns the file to you. + + 1. The Angular compiler imports the completed translation files, + replaces the original messages with translated text, and generates a new version of the application + in the target language. + + You build and deploy a separate version of the application for each supported language. + +a#i18n-attribute +.l-main-section +:marked + ## Mark text with the _i18n_ attribute + + The Angular `i18n` attribute is a marker for translatable content. + Place it on every element tag whose fixed text should be translated. + +.alert.is-helpful + :marked + `i18n` is not an Angular _directive_. It's a custom _attribute_, recognized by Angular tools and compilers. + +:marked + In the accompanying sample, an `

` tag displays a simple English language greeting which you will translate to French: ++makeExample('cb-i18n/ts/app/app.component.1.html', 'greeting', 'app/app.component.html')(format=".") +:marked + Add the `i18n` attribute to the tag to mark it for translation. + ++makeExample('cb-i18n/ts/app/app.component.1.html', 'i18n-attribute', 'app/app.component.html')(format=".") + +:marked + The translator may need a description of the message to translate it accurately. + Assign a description to the i18n attribute: + ++makeExample('cb-i18n/ts/app/app.component.1.html', 'i18n-attribute-desc', 'app/app.component.html')(format=".") + +:marked + The true _meaning_ of the text may require some application context. + Add a contextual meaning to the assigned string, separating it from the description with the `|` character: + ++makeExample('cb-i18n/ts/app/app.component.html', 'i18n-attribute-meaning', 'app/app.component.html')(format=".") + +:marked + While all appearance of a message with the _same_ meaning should have the _same_ translation, + a message with *different meanings* could have different translations. + The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file + to facilitiate contextually-specific transations. + +a#ng-xi18n +.l-main-section +:marked + ## Extract translatable text with the _ng-xi18n_ command + + Use the `ng-xi18n` extraction tool to generate a translation source file in an industry standard format. + + This is an Angular CLI tool based on the `ngc` compiler in the `@angular/compiler-cli` npm package. + If you haven't already installed the CLI and its `platform-server` peer dependency, do so now: + +code-example(language="sh" class="code-shell"). + npm install @angular/compiler-cli @angular/platform-server --save + +:marked + Open a terminal window at the root of the application project and enter the `ng-xi18n` command: + +code-example(language="sh" class="code-shell"). + ./node_modules/.bin/ng-xi18n + +:marked + By default the tool generates a translation file named **`messages.xlf`** in the + XML Localisation Interchange File Format (XLIFF, version 1.2). + +code-example(language="sh" class="code-shell"). + ./node_modules/.bin/ng-xi18n --i18nFormat=xmb + +.l-sub-section + :marked + Windows users may have to quote the command: + code-example(language="sh"). + "./node_modules/.bin/ng-xi18n" + :marked + Consider adding a convenience shortcut to the `scripts` section of the `package.json` + to make the command easier to remember and run: + code-example(format='.'). + "scripts": { + "i18n": "ng-xi18n", + ... + } + :marked + Now you can enter: + code-example(language="sh" class="code-shell"). + npm run i18n + +:marked + ### Other translation formats + + You can generate a file named **`messages.xmb`** in the + XML Message Bundle (XMB) format + by adding the `--i18nFormat=xmb` switch. + + This sample sticks with the _XLIFF_ format. + +a#translate +.l-main-section +:marked + ## Translate _le message textuel_ + + The `ng-xi18n` command generated a translation source file in the project root folder named `messages.xlf`. + The next step is to translate the English language template text into the specific language translation + files. The cookbook sample creates a French translation file. + +a#i18n-file-structure +:marked + ### Create an i18n project structure + + You will probably translate into more than one other language so it's a good idea + for the project structure to reflect your entire internationalization effort. + + One approach is to create an `i18n` folder with subfolders for each language or locale, e.g. `i18n/fr` for French. + This sample puts `i18n/fr` under the project root. + + Move the `messages.xlf` into the `i18n` folder where it will become the source for all language-specific translations. + Then copy `messages.xlf` into `i18n/fr` and rename it as `messages.fr.xlf` . + + Follow the same convention for each target language. + + ### Translate + In the real world, you send the `messages.fr.xlf` file to a French translator who would fill in the translations + using one of the + many XLIFF file editors. + + This sample file is easy to translate without a special editor or knowledge of French. + Open `messages.fr.xlf` and find the `` section: + ++makeExample('cb-i18n/ts/i18n/trans-unit.html', '', 'i18n/messages.fr.xlf ()')(format=".") +:marked + This XML element represents the translation of the `

` greeting tag you marked with the `i18n` attribute. + + Using the _source_, _description_, and _meaning_ elements to guide your translation, + replace the `` tag with the French greeting: ++makeExample('cb-i18n/ts/i18n/fr/messages.fr.xlf.html', 'trans-unit', 'i18n/fr/messages.fr.xlf (, after translation)')(format=".") +:marked + Note that the `id` is generated by the tool. Don't touch it. + Its value depends on the content of the message, its meaning, and its description. + Change any of these factors and the `id` changes as well. +.alert.is-helpful + :marked + Repeat the extraction process whenever you add new app messages or edit existing ones. + Be careful not to lose the previous translations. + Specialized software can help manage the change process. + +#app-pre-translation +:marked + ### The app before translation + + After the previous steps, the sample app _and_ its translation file are as follows: + ++makeTabs(` + cb-i18n/ts/app/app.component.html, + cb-i18n/ts/app/app.component.ts, + cb-i18n/ts/app/app.module.ts, + cb-i18n/ts/app/main.1.ts, + cb-i18n/ts/i18n/fr/messages.fr.xlf.html +`, '', ` + app/app.component.html, + app/app.component.ts, + app/app.module.ts, + app/main.ts, + i18n/fr/messages.fr.xlf +`) + +a#merge +.l-main-section +:marked + ## Merge the translation file + + To merge the translated text into component templates, + you compile the application with the completed translation file. + The process is the same whether the file is in `.xlf` format or + in one of the other formats (`.xlif` and `.xtb`) that Angular understands. + + You provide the Angular compiler with three new pieces of information: + * the translation file + * the translation file format + * the _Locale ID_ (`en-US` for instance) + + _How_ you provide this information depends upon whether you compile with + the JiT (_Just-in-Time_) compiler or the AoT (_Ahead-of-Time_) compiler. + + * with [JiT](#jit), you provide the information at bootstrap time. + * with [AoT](#aot), you pass the information as `ngc` options. + +a#jit +.l-main-section +:marked + ### Merge with the JiT compiler + + The JiT (_Just-in-Time_) compiler compiles the application in the browser as the application loads. + Translation with the JiT compiler is a dynamic process of ... + + 1. determining the language version for the current user, + 2. importing the appropriate language translation file as a string constant, + 3. creating corresponding translation providers to guide the JiT compiler, + 4. bootstrapping the application with those providers. + + Open `index.html` and revise the launch script as shown here: ++makeExample('cb-i18n/ts/index.html', 'i18n', 'index.html (launch script)')(format='.') +:marked + In this sample, the user's language is hardcoded as a global `document.locale` variable + in the `index.html`. + +a#text-plugin +:marked + ### SystemJS Text plugin + + Notice the SystemJS mapping of `text` to a `systemjs-text-plugin.js`. + With the help of a text pluglin, SystemJS can read any file as raw text and + return the contents as a string. + You'll need it to import the language translation file. + + SystemJS doesn't ship with a raw text plugin but it's easy to add. + Create the following `systemjs-text-plugin.js` in the root folder: ++makeExample('cb-i18n/ts/systemjs-text-plugin.js', null, 'systemjs-text-plugin.js')(format='.') +:marked + ### Create translation providers + + Three providers tell the JiT compiler how to translate the template texts for a particular language + while compiling the application: + + * `TRANSLATIONS` is a string containing the content of the translation file. + * `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlif` or `xtb` + * `LOCALE_ID` is the locale of the target language. + + The `getTranslationProviders` function in the following `app/i18n-providers.ts` + creates those providers based on the user's _locale_ + and the corresponding translation file: ++makeExample('cb-i18n/ts/app/i18n-providers.ts', null, 'app/i18n-providers.ts') +:marked + * It gets the locale from the global `document.locale` variable that was set in `index.html`. + + * If there is no locale or the language is English, there is no need to translate. + The function returns an empty `noProviders` array as a `Promise`. + It must return a `Promise` because this function could read a translation file asynchronously from the server. + + * It creates a transaction filename from the locale according to the name and location convention + [described earlier](#i18n-file-structure). + + * The `getTranslationsWithSystemJs` method reads the translation and returns the contents as a string. + Notice that it appends `!text` to the filename, telling SystemJS to use the [text plugin](#text-plugin). + + * The callback composes a providers array with the three translation providers. + + * Finally, `getTranslationProviders` returns the entire effort as a promise. + + ### Bootstrap the app with translation providers + + The Angular `bootstrapModule` method has a second, _options_ parameter + that can influence the behavior of the compiler. + + You'll create an _options_ object with the translation providers from `getTranslationProviders` + and pass it to `bootstrapModule`. + Open the `app/main.ts` and modify the bootstrap code as follows: ++makeExample('cb-i18n/ts/app/main.ts', null, 'app/main.ts')(format=".") +:marked + Notice that it waits for the `getTranslationProviders` promise to resolve before + bootstrapping the app. + + The app is now _internationalized_ for English and French and there is a clear path for adding + more languages. + +a#aot +.l-main-section +:marked + ### _Internationalize_ with the AoT compiler + + The JiT compiler translates the application into the target language while compiling dynamically in the browser. + That's flexible but may not be fast enough for your users. + + The AoT (_Ahead-of-Time_) compiler is part of a build process that produces a small, fast, ready-to-run application package. + When you internationalize with the AoT compiler, you pre-build a separate application package for each + language. Then in the host web page (`index.html`), you determine which language the user needs + and serve the appropriate application package. + + This cookbook doesn't cover how to build multiple application packages and + serve them according to the user's language preference. + It does explain the few steps necessary to tell the AoT to apply a translations file. + + Internationalization with the AoT compiler requires some setup specifically for AoT. + Start with application project as shown [just before merging the translation file](#app-pre-translationStart) + and refer to the [AoT cookbook](aot-compiler.html) to make it _AoT-ready_. + + Next, issue an `ngc` compile command for each supported language (including English). + The result is a separate version of the application for each language. + + Tell AoT how to translate by adding three options to the `ngc` command: + * `--i18nFile`: the path to the translation file + * `--locale`: the name of the locale + * `--i18nFormat`: the format of the localization file + + For this sample, the French language command would be +code-example(language="sh" class="code-shell"). + ./node_modules/.bin/ngc --i18nFile=./i18n/fr/messages.fr.xlf --locale=fr --i18nFormat=xlf + +.l-sub-section + :marked + Windows users may have to quote the command: + code-example(language="sh" class="code-shell"). + "./node_modules/.bin/ngc" --i18nFile=./i18n/fr/messages.fr.xlf --locale=fr --i18nFormat=xlf diff --git a/public/docs/ts/latest/guide/architecture.jade b/public/docs/ts/latest/guide/architecture.jade index 62c93dc41a..223bbb2200 100644 --- a/public/docs/ts/latest/guide/architecture.jade +++ b/public/docs/ts/latest/guide/architecture.jade @@ -444,7 +444,7 @@ block ts-decorator :marked - `moduleId: module.id`: sets the base for module-relative loading of the `templateUrl`. - - `moduleId: module.id`: 为`templateUrl`的模块相对加载提供基础。 + - `moduleId`: 为与模块相关的URL(如`templateUrl`)提供基地址。 - `selector`: CSS selector that tells Angular to create and insert an instance of this component where it finds a `` tag in *parent* HTML. @@ -458,15 +458,6 @@ block ts-decorator - `templateUrl`:组件HTML模板的模块相对地址,我们在[前面](#templates)展示过它。 - - `directives`: !{_array} of the components or directives that *this* template requires. - In the last line of `hero-list.component.html`, Angular inserts a `HeroDetailComponent` - in the space indicated by `` tags. - Angular does so only if `HeroDetailComponent` is in this `directives` !{_array}. - - - `directives` - 一个数组,包含*此*模板需要依赖的组件或指令。 - 看看模板的最后一行,这表示我们期待Angular把`HeroDetailComponent`的实例放在``标签中。 - 但是,只有在`directives`数组中有`HeroDetailComponent`的时候,Angular才会这么做。 - - `providers`: !{_array} of **dependency injection providers** for services that the component requires. This is one way to tell Angular that the component's constructor requires a `HeroService` so it can get the list of heroes to display. diff --git a/public/docs/ts/latest/guide/forms.jade b/public/docs/ts/latest/guide/forms.jade index fb3b128463..2e40765c17 100644 --- a/public/docs/ts/latest/guide/forms.jade +++ b/public/docs/ts/latest/guide/forms.jade @@ -375,7 +375,7 @@ code-example(format=""). :marked .l-sub-section :marked - There is only one changes: + There is only one change: 仅有的一处修改是: diff --git a/public/docs/ts/latest/guide/style-guide.jade b/public/docs/ts/latest/guide/style-guide.jade index 36c69bcb24..9fe025840a 100644 --- a/public/docs/ts/latest/guide/style-guide.jade +++ b/public/docs/ts/latest/guide/style-guide.jade @@ -1,12 +1,5 @@ include ../_util-fns -.alert.is-important - :marked - We are still preparing style recommendations for the new NgModules feature - introduced in RC5 and will add it to the style guide soon. - - 我们正在为在RC5中引进的新`NgModules`特征编写风格指南,并将很快添加到本风格指南中。 - :marked Welcome to the Angular Style Guide @@ -15,14 +8,13 @@ include ../_util-fns ## Purpose ## 目的 - If you are looking for an opinionated style guide for syntax, conventions, and structuring Angular applications, then step right in. + Looking for an opinionated guide to Angular syntax, conventions, and application structure? + Step right in! + This style guide presents our preferred conventions and, as importantly, explains why. 如果你在寻找一份关于语法、约定和Angular应用程序的组织结构的风格指南,那你就来对了。 + 本风格指南提供了我们所提倡的约定,但最重要的是,解释了为什么。 - The purpose of this style guide is to provide guidance on building Angular applications by showing the conventions we use and, more importantly, why we choose them. - - 本指南的目的是为开发Angular应用程序提供指导原则,展示我们所遵循的约定,更重要的是,解释我们为什么要选择这些约定。 - .l-main-section :marked @@ -39,7 +31,10 @@ include ../_util-fns .s-rule.do :marked - **Do** is one that should always be followed. _Always_ might be a bit too strong of a word. Guidelines that literally should always be followed are extremely rare. On the other hand, we need a really unusual case for breaking a *Do* guideline. + **Do** is one that should always be followed. + _Always_ might be a bit too strong of a word. + Guidelines that literally should always be followed are extremely rare. + On the other hand, you need a really unusual case for breaking a *Do* guideline. **坚持**意味着总是应该遵循的约定。_总是_可能有点太强。应该_总是_遵循的指导原则非常少见。但是,只有遇到非常不寻常的情况才能打破*坚持*的原则。 @@ -55,7 +50,7 @@ include ../_util-fns .s-rule.avoid :marked - **Avoid** indicates something we should almost never do. Code examples to *avoid* have an unmistakeable red header. + **Avoid** indicates something you should almost never do. Code examples to *avoid* have an unmistakeable red header. **避免**标志着我们决不应该做的事。需要*避免*的代码范例会有不会被忽视的红色标题。 .l-main-section @@ -91,9 +86,9 @@ a(id='toc') 1. [代码约定](#coding-conventions) - 1. [Application Structure](#application-structure) + 1. [App Structure and Angular Modules](#app-structure-and-angular-modules) - 1. [应用程序结构](#application-structure) + 1. [应用程序结构与模块划分](#app-structure-and-angular-modules) 1. [Components](#components) @@ -124,10 +119,11 @@ a(id='toc') ## Single Responsibility ## 单一职责 - We apply the [Single Responsibility Principle](https://wikipedia.org/wiki/Single_responsibility_principle) to all Components, Services, and other symbols we create. This helps make our app cleaner, easier to read and maintain, and more testable. + Apply the [Single Responsibility Principle](https://wikipedia.org/wiki/Single_responsibility_principle) to all components, services, and other symbols. + This helps make the app cleaner, easier to read and maintain, and more testable. 我们遵循[单一职责原则](https://en.wikipedia.org/wiki/Single_responsibility_principle)来创建的所有组件、服务和其它标志等。这样能帮助我们把应用程序弄的干净整洁,易于阅读、维护和测试。 - + ### Rule of One ### 单一法则 #### Style 01-01 @@ -291,7 +287,7 @@ a(href="#toc") 回到顶部 .s-why :marked - **Why?** The naming conventions should simply help us find our code faster and make it easier to understand. + **Why?** The naming conventions should simply help find desited code faster and make it easier to understand. **为何?**命名约定最直接的目的是:帮我们快速找到代码并让它们更容易理解。 @@ -335,10 +331,10 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** use conventional type names including `.service`, `.component`, `.pipe`. + **Do** use conventional type names including `.service`, `.component`, `.pipe`, `.module`, `.directive`. Invent additional type names if you must but take care not to create too many. - **坚持**使用惯用的后缀来描述类型,比如`*.service`、`*.component`、`*.pipe`。 + **坚持**使用惯用的后缀来描述类型,比如`*.service`、`*.component`、`*.pipe`、`.module`、`.directive`。 创建额外的类型名字,但你必须注意不要创建太多。 @@ -376,8 +372,8 @@ a(href="#toc") 回到顶部 .l-main-section :marked - ### Components and Directives - ### 组件与指令命名 + ### Symbols and File Names + ### 符号名与文件名 #### Style 02-03 #### 风格02-03 @@ -389,34 +385,34 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** use upper camel case for symbols. Match the name of the symbol to the naming of the file. + **Do** use upper camel case for class names. Match the name of the symbol to the name of the file. - **坚持**使用大写驼峰命名法来命名所有符号(类)。保持符号的名字与它所在的文件名字相同。 + **坚持**使用大写驼峰命名法来命名所有类名。保持符号的名字与它所在的文件名字相同。 .s-rule.do :marked - **Do** append the symbol name with the suffix that it represents. + **Do** append the symbol name with the conventional suffix for a thing of that type + (e.g., `Component`, `Directive`, `Module`, `Pipe`, `Service`). - **坚持**把符号的类型(比如组件、服务、指令等)附加到符号名的后面。 - + **坚持**在符号名后面追加约定的类型后缀(比如:`Component`、`Directive`、`Module`、`Pipe`、`Service`)。 +.s-rule.do + :marked + **Do** give the filename the conventional suffix for a file of that type + (e.g., `.component.ts`, `.directive.ts`, `.module.ts`, `.pipe.ts`, `.service.ts`). + + **坚持**在文件名后面追加约定的类型后缀(比如`.component.ts`、`.directive.ts`、`.module.ts`、`.pipe.ts`、`.service.ts`)。 .s-why :marked **Why?** Provides a consistent way to quickly identify and reference assets. - **为何?**提供前后一致的方法迅速辨识和引用东西。 + **为何?**提供一种一致的方式,以快速标识和引用资产。 -.s-why +.s-why.s-why-last :marked **Why?** Upper camel case is conventional for identifying objects that can be instantiated using a constructor. - **为何?**大写驼峰命名法约定用来辨识出那些可通过构造函数来实例化的对象。 - -.s-why.s-why-last - :marked - **Why?** The `Component` suffix is more commonly used and is more explicitly descriptive. - - **为何?**`Component`后缀是常见的用法,它具有精准的描述性。 + **为何?**大驼峰命名法是用来识别那些能通过构造函数进行实例化的对象的命名约定。 - var top="vertical-align:top" table(width="100%") @@ -433,7 +429,7 @@ table(width="100%") td code-example. @Component({ ... }) - export class AppComponent {} + export class AppComponent { } td :marked app.component.ts @@ -441,7 +437,7 @@ table(width="100%") td code-example. @Component({ ... }) - export class HeroesComponent + export class HeroesComponent { } td :marked heroes.component.ts @@ -449,7 +445,7 @@ table(width="100%") td code-example. @Component({ ... }) - export class HeroListComponent + export class HeroListComponent { } td :marked hero-list.component.ts @@ -457,7 +453,7 @@ table(width="100%") td code-example. @Component({ ... }) - export class HeroDetailComponent + export class HeroDetailComponent { } td :marked hero-detail.component.ts @@ -465,10 +461,34 @@ table(width="100%") td code-example. @Directive({ ... }) - export class ValidationDirective + export class ValidationDirective { } td :marked validation.directive.ts + tr(style=top) + td + code-example. + @NgModule({ ... }) + export class AppModule + td + :marked + app.module.ts + tr(style=top) + td + code-example. + @Pipe({ name: 'initCaps' }) + export class InitCapsPipe implements PipeTransform { } + td + :marked + init-caps.pipe.ts + tr(style=top) + td + code-example. + @Injectable() + export class UserProfileService { } + td + :marked + user-profile.service.ts :marked a(href="#toc") Back to top @@ -533,7 +553,7 @@ table(width="100%") td code-example. @Injectable() - export class HeroDataService {} + export class HeroDataService { } td :marked hero-data.service.ts @@ -541,7 +561,7 @@ table(width="100%") td code-example. @Injectable() - export class CreditService {} + export class CreditService { } td :marked credit.service.ts @@ -549,7 +569,7 @@ table(width="100%") td code-example. @Injectable() - export class Logger {} + export class Logger { } td :marked logger.service.ts @@ -572,11 +592,17 @@ a(href="#toc") 回到顶部 **坚持**把应用的引导程序和平台相关的逻辑放到名为`main.ts`的文件里。 +.s-rule.do + :marked + **Do** include error handling the bootstrapping logic. + + **坚持**在“引导”逻辑中包含错误处理代码。 + .s-rule.avoid :marked - **Avoid** putting app logic in the `main.ts`. Instead consider placing it in a Component or Service. + **Avoid** putting app logic in the `main.ts`. Instead consider placing it in a component or service. - **避免**把应用逻辑放到`main.ts`里。考虑把它放到组件或服务里面。 + **避免**把应用逻辑放在`main.ts`中,而应该考虑把它们放进组件或服务里。 .s-why :marked @@ -590,6 +616,9 @@ a(href="#toc") 回到顶部 **为何?**这是从其它技术平台借鉴的一个常用约定。 ++makeExample('style-guide/ts/02-05/main.ts', '', 'main.ts') +:marked + a(href="#toc") Back to top a(href="#toc") 回到顶部 @@ -604,7 +633,7 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** Use lower camel case for naming the selectors of our directives. + **Do** Use lower camel case for naming the selectors of directives. **坚持**使用小驼峰命名法来命名指令的选择器。 @@ -634,9 +663,17 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** use a custom prefix for the selector of our components. For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the prefix `admin` represents an admin feature area. + **Do** use a hyphenated, lowercase element selector value (e.g. `admin-users`). - **坚持**为组件的选择器使用自定义前缀。比如,前缀`tod`是从**T**our **o**f **H**eros来的,前缀`admin`代表了admin的特性区域。 + **坚持**使用带连字符的小写元素选择器的值(比如`admin-users`)。 + +.s-rule.do + :marked + **Do** use a custom prefix for a component selector. + For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the prefix `admin` represents an admin feature area. + + **坚持**为组件选择器使用自定义前缀。 + 比如`toh`前缀表示**T**our **o**f **H**eroes(英雄指南),而前缀`admin表示管理特性区。 .s-rule.do :marked @@ -646,21 +683,21 @@ a(href="#toc") 回到顶部 .s-why :marked - **Why?** Prevents name collisions. + **Why?** Prevents element name collisions with components in other apps and with native HTML elements. - **为何?**防止名字冲突。 + **为何?**防止与来自其它应用中的组件和原生HTML元素发生命名冲突。 .s-why :marked - **Why?** Makes it easier to promote and share our feature in other apps. + **Why?** Makes it easier to promote and share the component in other apps. - **为何?**把我们的代码推广和共享到其它应用中会更容易。 + **为何?**把我们的组件推广和共享到其它应用中会更容易。 .s-why.s-why-last :marked - **Why?** Our Components and elements are easily identified. + **Why?** Components are easy to identify in the DOM. - **为何?**我们组件和元素更容易被识别。 + **为何?**组件在DOM中更容易被区分出来。 +makeExample('style-guide/ts/02-07/app/heroes/hero.component.avoid.ts', 'example', 'app/heroes/hero.component.ts')(avoid=1) :marked @@ -682,9 +719,15 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** use a custom prefix for the selector of our directives (for instance below we use the prefix `toh` from **T**our **o**f **H**eroes). + **Do** use a custom prefix for the selector of directives (e.g, the prefix `toh` from **T**our **o**f **H**eroes). - **坚持**为指令的选择器使用自定义的前缀(比如下面例子中,我们使用前缀`toh`,取自**T**our **o**f **H**eroes)。 + **坚持**为指令的选择器使用自定义前缀(比如前缀`toh`来自**T**our **o**f **H**eroes)。 + +.s-rule.do + :marked + **Do** spell non-element selectors in lower camel case unless the selector is meant to match a native HTML attribute. + + **坚持**用小驼峰形式拼写非元素选择器,除非该选择器就是要用来匹配某个原生HTML属性的。 .s-why :marked @@ -694,7 +737,7 @@ a(href="#toc") 回到顶部 .s-why.s-why-last :marked - **Why?** Our Directives are easily identified. + **Why?** Directives are easily identified. **为何?**指令更加容易被识别。 @@ -900,6 +943,121 @@ a(href="#toc") Back to top a(href="#toc") 回到顶部 +.l-main-section +:marked + ### Angular NgModule Names + ### Angular NgModule命名 + #### Style 02-12 + +.s-rule.do + :marked + **Do** append the symbol name with the suffix `Module`. + + **坚持**为符号名追加`Module`后缀 + +.s-rule.do + :marked + **Do** give the file name the `.module.ts` extension. + + **坚持**为文件名添加`.module.ts`扩展名。 + +.s-rule.do + :marked + **Do** name the module after the feature and folder it resides in. + + **坚持**用特性名和所在目录命名模块。 + +.s-why + :marked + **Why?** Provides a consistent way to quickly identify and reference modules. + + **为何?**提供一个一致的方式来快速的标出和引用模块。 + +.s-why + :marked + **Why?** Upper camel case is conventional for identifying objects that can be instantiated using a constructor. + + **为何?**大驼峰命名法是一种命名约定,用来标出可用构造函数实例化的对象。 + +.s-why.s-why-last + :marked + **Why?** Easily identifies the module as the root of the same named feature. + + **为何?**很容易就能看出这个模块是同名特性的跟模块。 + +.s-rule.do + :marked + **Do** suffix a _RoutingModule_ class name with `RoutingModule`. + + **坚持**为*RoutingModule*类名添加`RoutingModule`后缀。 + +.s-rule.do + :marked + **Do** end the filename of a _RoutingModule_ with `-routing.module.ts`. + + **坚持** *RoutingModule*的文件名用`-routing.module.ts`结尾。 + +.s-why.s-why-last + :marked + **Why?** A `RoutingModule` is a module dedicated exclusively to configuring the Angular router. + A consistent class and file name convention make these modules easy to spot and verify. + + **为何?**`RoutingModule`是一种专门用来配置Angular路由器的模块。 + “让类名和文件名保持一致”这项约定可以让这些模块易于跟踪和验证。 + +- var top="vertical-align:top" +table(width="100%") + col(width="50%") + col(width="50%") + tr + th Symbol Name + th File Name + tr(style=top) + td + code-example. + @NgModule({ ... }) + export class AppModule { } + td + :marked + app.module.ts + tr(style=top) + td + code-example. + @NgModule({ ... }) + export class HeroesModule { } + td + :marked + heroes.module.ts + tr(style=top) + td + code-example. + @NgModule({ ... }) + export class VillainsModule { } + td + :marked + villains.module.ts + tr(style=top) + td + code-example. + @NgModule({ ... }) + export class AppRoutingModule { } + td + :marked + app-routing.module.ts + tr(style=top) + td + code-example. + @NgModule({ ... }) + export class HeroesRoutingModule { } + td + :marked + heroes-routing.module.ts +:marked + +a(href="#toc") Back to top + +a(href="#toc") 回到顶部 + .l-main-section :marked ## Coding Conventions @@ -928,14 +1086,15 @@ a(href="#toc") 回到顶部 .s-why.s-why-last :marked - **Why?** Classes can be instantiated and construct an instance. We often use upper camel case to indicate a constructable asset. + **Why?** Classes can be instantiated and construct an instance. + By convention, upper camel case indicates a constructable asset. - **为何?**类可以被实例化。我们通常使用大写驼峰命名约定来标示可被构造出来的东西。 + **为何?**类可以被实例化和构造出实例。根据约定,用大写驼峰命名法来标示可被构造出来的东西。 -+makeExample('style-guide/ts/03-01/app/shared/exception.service.avoid.ts', 'example', 'app/shared/exception.service.ts')(avoid=1) ++makeExample('style-guide/ts/03-01/app/core/exception.service.avoid.ts', 'example', 'app/shared/exception.service.ts')(avoid=1) :marked -+makeExample('style-guide/ts/03-01/app/shared/exception.service.ts', 'example', 'app/shared/exception.service.ts') ++makeExample('style-guide/ts/03-01/app/core/exception.service.ts', 'example', 'app/shared/exception.service.ts') :marked a(href="#toc") Back to top @@ -964,10 +1123,10 @@ a(href="#toc") 回到顶部 .s-why.s-why-last :marked - TypeScript helps enforce that intent by requiring immediate initialization and by + **Why?** TypeScript helps enforce that intent by requiring immediate initialization and by preventing subsequent re-assignment. - TypeScript会要求在声明时立即初始化,并阻止对其再次赋值,以确保达成我们的意图。 + **为何?**TypeScript会要求在声明时立即初始化,并阻止对其再次赋值,以确保达成我们的意图。 .s-rule.consider :marked @@ -999,13 +1158,14 @@ a(href="#toc") 回到顶部 .s-why.s-why-last :marked - **Why?** Although we recommend creating _new_ constants in lower camel case, - the tradition of UPPER_SNAKE_CASE remains popular and pervasive, + **Why?** The tradition of UPPER_SNAKE_CASE remains popular and pervasive, especially in third party modules. + It is rarely worth the effort to change them or the risk of breaking existing code and documentation. - **为何?**虽然我们建议用小驼峰命名法创建_新的_常量,但传统的大写驼峰命名法仍然很流行、很普遍,特别是在第三方模块中。 + **为何?**传统的大写蛇形命名法(UPPER_SNAKE_CASE)仍然很流行、很普遍,特别是在第三方模块中。 + 修改它们带不来多大价值,同时还会有破坏现有代码和文档的风险。 -+makeExample('style-guide/ts/03-02/app/shared/data.service.ts', '', 'app/shared/data.service.ts') ++makeExample('style-guide/ts/03-02/app/core/data.service.ts', '', 'app/shared/data.service.ts') :marked a(href="#toc") Back to top @@ -1032,16 +1192,41 @@ a(href="#toc") 回到顶部 **考虑**不要在接口名字前面加`I`前缀。 +.s-rule.consider + :marked + **Consider** using a class instead of an interface. + + **考虑**用类代替接口。 + +.s-why + :marked + **Why?** TypeScript guidelines + discourage the "I" prefix. + + **为何?**TypeScript指导原则不建议使用“I”前缀。 + +.s-why + :marked + **Why?** A class alone is less code than a _class-plus-interface_. + + **为何?**单独一个类的代码量小于*类+接口*。 + +.s-why + :marked + **Why?** A class can act as an interface (use `implements` instead of `extends`). + + **为何?**类实际上就是接口(只是要用`implements`代替`extends`而已)。 + .s-why.s-why-last :marked - **Why?** When we use types, we can often simply use the class as the type. + **Why?** An interface-class can be a provider lookup token in Angular dependency injection. - **为何?**当我们使用类型时,我们经常简单地使用类来作为类型。 + **为何?**在Angular依赖注入系统中,接口类可以作为服务提供商的查阅令牌。 -+makeExample('style-guide/ts/03-03/app/shared/hero-collector.service.avoid.ts', 'example', 'app/shared/hero-collector.service.ts')(avoid=1) ++makeExample('style-guide/ts/03-03/app/core/hero-collector.service.avoid.ts', 'example', 'app/shared/hero-collector.service.ts')(avoid=1) :marked -+makeExample('style-guide/ts/03-03/app/shared/hero-collector.service.ts', 'example', 'app/shared/hero-collector.service.ts') ++makeExample('style-guide/ts/03-03/app/core/hero-collector.service.ts', 'example', 'app/shared/hero-collector.service.ts') :marked a(href="#toc") Back to top @@ -1086,10 +1271,10 @@ a(href="#toc") 回到顶部 **为何?**TypeScript工具让识别私有或公有属性和方法变得很简单。 -+makeExample('style-guide/ts/03-04/app/shared/toast.service.avoid.ts', 'example', 'app/shared/toast.service.ts')(avoid=1) ++makeExample('style-guide/ts/03-04/app/core/toast.service.avoid.ts', 'example', 'app/shared/toast.service.ts')(avoid=1) :marked -+makeExample('style-guide/ts/03-04/app/shared/toast.service.ts', 'example', 'app/shared/toast.service.ts') ++makeExample('style-guide/ts/03-04/app/core/toast.service.ts', 'example', 'app/shared/toast.service.ts') :marked a(href="#toc") Back to top @@ -1133,23 +1318,23 @@ a(href="#toc") 回到顶部 #### Style 03-06 #### 风格03-06 -.s-rule.do +.s-rule.consider :marked - **Do** leave one empty line between third party imports and imports of code we created. + **Consider** leaving one empty line between third party imports and application imports. **坚持**在第三方导入和自己代码的导入之间留一个空行。 -.s-rule.do +.s-rule.consider :marked - **Do** list import lines alphabetized by the module. + **Consider** listing import lines alphabetized by the module. - **坚持**按模块名字的字母顺排列导入行。 + **考虑**按模块名字的字母顺排列导入行。 -.s-rule.do +.s-rule.consider :marked - **Do** list destructured imported assets alphabetically. + **Consider** listing destructured imported assets alphabetically. - **坚持**在解构表达式中按字母顺序排列导入的东西。 + **考虑**在解构表达式中按字母顺序排列导入的东西。 .s-why :marked @@ -1176,17 +1361,27 @@ a(href="#toc") 回到顶部 .l-main-section :marked - ## Application Structure - ## 应用程序结构 + ## App Structure and Angular Modules + ## 应用程序的结构与Angular模块划分 - Have a near term view of implementation and a long term vision. Start small but keep in mind where the app is heading down the road. + Have a near-term view of implementation and a long-term vision. Start small but keep in mind where the app is heading down the road. 准备一个短期和一个长期的实施方案。从零开始,但要时刻考虑应用程序接下来要走的路。 - - All of the app's code goes in a folder named `app`. All content is 1 feature per file. Each component, service, and pipe is in its own file. All 3rd party vendor scripts are stored in another folder and not in the `app` folder. We didn't write them and we don't want them cluttering our app. Use the naming conventions for files in this guide. - 把所有应用程序的源代码都放到名叫`app`的目录里。所有内容都遵循每个文件单个特性的原则。每个组件、服务和管道都在自己的文件里。 - 所有第三方程序包都被保存到其它目录里而不在`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`的目录里。 + 所有特性区都在自己的文件夹中,带有他们自己的Angular模块。 + + All content is 1 asset per file. Each component, service, and pipe is in its own file. + All 3rd party vendor scripts are stored in another folder and not in the `app` folder. + You didn't write them and you don't want them cluttering app. + Use the naming conventions for files in this guide. + + 所有内容都遵循每个文件单个特性的原则。每个组件、服务和管道都在自己的文件里。 + 所有第三方程序包都被保存到其它目录里而不在`app`目录里,我们不会修改它们,所以不希望它们弄乱我们的应用程序。使用本指南介绍的文件命名约定。 a(href="#toc") Back to top @@ -1201,9 +1396,13 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** structure the app such that we can `L`ocate our code quickly, `I`dentify the code at a glance, keep the `F`lattest structure we can, and `T`ry to be DRY. + **Do** structure the app such that you can `L`ocate code quickly, + `I`dentify the code at a glance, + keep the `F`lattest structure you can, and + `T`ry to be DRY. - **坚持**组织应用的结构,达到这些目的:快速定位(`L`ocate)代码、一眼识别(`I`dentify)代码、尽量保持平面化结构(`F`lattest)和尝试`T`ry遵循不重复自己DRY - Do Not Repeat Yourself约定。 + **坚持**组织应用的结构,达到这些目的:快速定位(`L`ocate)代码、一眼识别(`I`dentify)代码、尽量保持平面化结构(`F`lattest)和尝试`T`ry遵循不重复自己DRY - Do Not Repeat Yourself原则。 + .s-rule.do :marked @@ -1213,9 +1412,11 @@ a(href="#toc") 回到顶部 .s-why.s-why-last :marked - **Why?** LIFT Provides a consistent structure that scales well, is modular, and makes it easier to increase developer efficiency by finding code quickly. Another way to check our app structure is to ask ourselves: How quickly can we open and work in all of the related files for a feature? + **Why?** LIFT Provides a consistent structure that scales well, is modular, and makes it easier to increase developer efficiency by finding code quickly. + To confirm your intuition about a particular structure, ask: + _can I quickly open and start work in all of the related files for this feature_? - **为何?**LIFT提供了前后一致的结构,它具有扩展性强、模块化的特性。因为容易快速锁定代码,所以提高了开发者的效率。另外,检查应用结构的方法是问问自己:我们打开和编辑与某个特性相关的所有文件的速度如何? + **为何?**LIFT提供了前后一致的结构,它具有扩展性强、模块化的特性。因为容易快速锁定代码,所以提高了开发者的效率。另外,检查应用结构是否合理的方法是问问自己:我们能快速打开与此特性有关的文件并开始工作吗? a(href="#toc") Back to top a(href="#toc") 回到顶部 @@ -1230,15 +1431,22 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** make locating our code intuitive, simple and fast. + **Do** make locating code intuitive, simple and fast. **坚持**直观、简单和快速的定位我们的代码。 .s-why.s-why-last :marked - **Why?** We find this to be super important for a project. If we cannot find the files we need to work on quickly, we will not be able to work as efficiently as possible, and the structure will need to change. We may not know the file name or where its related files are, so putting them in the most intuitive locations and near each other saves a ton of time. A descriptive folder structure can help with this. + **Why?** + To work efficiently you must be able to find files quickly, + especially when you do not know (or do not remember) the file _names_. + Keeping related files near each other in an intuitive location saves time. + A descriptive folder structure makes a world of difference to you and the people who come after you. - **为何?**定位对项目是非常重要的。如果我们不能快速找到需要工作的文件,我们就不可能在最佳效率状态下面工作,结构就需要更换。我们可能不知道文件的名称或者文件所在目录名,所以我们把它们放到直观的地方,一个挨着一个,这样可以节省很多时间。坚持说明性强的文件结构会有很大帮助。 + **为何?** + 要想高效的工作,就必须能迅速找到文件,特别是当不知道(或不记得)文件*名*时。 + 把相关的文件一起放在一个直观的位置可以节省时间。 + 富有描述性的目录结构会让你和后面的维护者眼前一亮。 a(href="#toc") Back to top @@ -1253,7 +1461,7 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** name the file such that we instantly know what it contains and represents. + **Do** name the file such that you instantly know what it contains and represents. **坚持**命名文件到这个程度:可以从名字立刻知道它包含了什么,代表了什么。 @@ -1271,15 +1479,19 @@ a(href="#toc") 回到顶部 .s-why.s-why-last :marked - **Why?** We spend less time hunting and pecking for code, and become more efficient. If this means we want longer file names, then so be it. + **Why?** Spend less time hunting and pecking for code, and become more efficient. + Longer file names are far better than _short-but-obscure_ abbreviated names. - **为何?**我们花费更少的时间来查找和琢磨代码,工作更有效率。如果这意味着更长的文件名,长就长吧。 + **为何?**花费更少的时间来查找和琢磨代码,就会变得更有效率。 + 较长的文件名远胜于*较短却容易混淆的*缩写名。 .l-sub-section :marked - There are deviations of the 1 per file rule when we have a set of very small features that are all related to each other, as they are still easily identifiable. + It may be advantageous to deviate from the _one-thing-per-file_ rule when + you have a set of small, closely-related features that are better discovered and understood + in a single file than as multiple files. Be wary of this loophole. - 当我们有一套非常小并且互相关联的特性时,我们可能不必坚持单文件单组件的约定,因为它们仍然非常易于被识别。 + 当你有一组小型、紧密相关的特性时,违反*一物一文件*的规则可能会更好,这种情况下单一文件可能会比多个文件更容易发现和理解。注意这个例外。 a(href="#toc") Back to top @@ -1301,15 +1513,37 @@ a(href="#toc") 回到顶部 .s-rule.consider :marked - **Consider** creating fodlers when we get to seven or more files. + **Consider** creating sub-folders when a folder reaches seven or more files. - **考虑**当我们有7个或更多文件时才新建目录。 + **考虑**当同一目录下达到7个或更多个文件时创建子目录。 -.s-why.s-why-last +.s-rule.consider :marked - **Why?** Nobody wants to search seven levels of folders to find a file. In a folder structure there is no hard and fast number rule, but when a folder has seven to ten files, that may be time to create subfolders. We base it on our comfort level. Use a flatter structure until there is an obvious value (to help the rest of LIFT) in creating a new folder. + **Consider** configuring the IDE to hide distracting, irrelevant files such as generated `.js` and `.js.map` files. - **为何?**没有人愿意搜索7层目录来找一个文件。在目录结构中,没有硬数字约定,但是当目录有七到十个文件时,就是需要新建子目录的时候了。这是基于舒适级别而定的。以平面化结构开始,在有很明显的需求时再新建目录(来配合其它LIFT约定) + **考虑**配置IDE,以隐藏无关的文件,比如生成出来的`.js`文件和`.js.map`文件等。 + +s-why.s-why-last + :marked + **Why?** No one wants to search for a file through seven levels of folders. + A flat structure is easy to scan. + + **为何?**没人想要在超过七层的目录中查找文件。扁平的结构有利于搜索。 + + On the other hand, + psychologists believe + that humans start to struggle when the number of adjacent interesting things exceeds nine. + So when a folder has ten or more files, it may be time to create subfolders. + + 另一方面,心理学家们相信, + 当关注的事物超过9个时,人类就会开始感到吃力。 + 所以,当一个文件夹中有10个或更多个文件时,可能就是创建子目录的时候了。 + + Base your decision on your comfort level. + Use a flatter structure until there is an obvious value to creating a new folder. + + 还是根据你自己的舒适度而定吧。 + 除非创建新文件夹能有显著的价值,否则尽量使用扁平结构。 a(href="#toc") Back to top @@ -1330,15 +1564,21 @@ a(href="#toc") 回到顶部 .s-rule.avoid :marked - **Avoid** being so DRY that we sacrifice readability. + **Avoid** being so DRY that you sacrifice readability. **避免**过度DRY,以致牺牲了阅读性。 .s-why.s-why-last :marked - **Why?** Being DRY is important, but not crucial if it sacrifices the others in LIFT, which is why we call it T-DRY. We don’t want to type `hero-view.component.html` for a view because, well, it’s obviously a view. If it is not obvious or by convention, then we name it. + **Why?** Being DRY is important, but not crucial if it sacrifices the other elements of LIFT. + That's why its calle _T-DRY_. + For example, it's redundant to name a component, `hero-view.component.html` because a component is obviously a view. + But if something is not obvious or departs from a convention, then spell it out. - **为何?**虽然不重复自己约定很重要,但是如果要牺牲其它的LIFT约定,它就不是最重要的,这就是为什么我们说**尝试**不重复自己(T-DRY)。我们不愿意为了视图使用`hero-view.component.html`,因为它很明显就是一个视图。如果它不是很明显,那么我们就把视图单词加到它的名字里。 + **为何?**虽然DRY(不要重复你自己)很重要,但如果要以牺牲LIFT的其它原则为代价,那就不值得了。 + 这也就是为什么它被称为*T-DRY*。 + 比如,把组件命名为`hero-view.component.html`是多余的,因为组件显然就是一个视图(view)。 + 但如果它不是这么显著,或不符合常规,那就把它写出来。 a(href="#toc") Back to top @@ -1371,15 +1611,15 @@ a(href="#toc") 回到顶部 .s-rule.consider :marked - **Consider** creating a folder for each component including its `.ts`, `.html`, `.css` and `.spec` file. + **Consider** creating a folder for a component when is has multiple accompanying files (`.ts`, `.html`, `.css` and `.spec`). - **考虑**为每个组件新建一个目录,保存它的`.ts`,`.html`,`.css`,`.spec`等文件。 + **坚持**如果组件具有多个相互合作的文件(`.ts`、`.html`、`.css`和`.spec`),那就为它创建一个文件夹。 .s-why :marked - **Why?** Helps us keep the app structure small and easy to maintain in the early stages, while being easy to evolve as the app grows. + **Why?** Helps keep the app structure small and easy to maintain in the early stages, while being easy to evolve as the app grows. - **为何?** 帮助我们在早期保持应用结构的精简与可维护性,同时保证在应用程序成长的过程中,结构易于演化。 + **为何?**在早期阶段能够帮助保持应用的结构小巧而且易于维护,这样当应用增长时就会更容易进化了。 .s-why.s-why-last :marked @@ -1387,182 +1627,44 @@ a(href="#toc") 回到顶部 **为何?**组件通常有四个文件(例如`*.html`、 `*.css`、 `*.ts` 和 `*.spec.ts`),它们很容易把一个目录弄乱。 -.example-title Overall Folder and File Structure 整体目录和文件结构 +a(id='file-tree') +:marked + Folder and File Structure + + 目录和文件结构 + .filetree .file src .children .file app .children + .file core + .children + .file core.module.ts + .file exception.service.ts|spec.ts + .file user-profile.service.ts|spec.ts .file heroes .children .file hero .children .file hero.component.ts|html|css|spec.ts - .file index.ts .file hero-list .children .file hero-list.component.ts|html|css|spec.ts - .file index.ts .file shared .children + .file hero-button.component.ts|html|css|spec.ts .file hero.model.ts .file hero.service.ts|spec.ts - .file index.ts .file heroes.component.ts|html|css|spec.ts - .file index.ts + .file heroes.module.ts + .file heroes-routing.module.ts .file shared .children - .file ... - .file app.component.ts|html|css|spec.ts - .file main.ts - .file index.html - .file ... -:marked - -.l-sub-section - :marked - While we prefer our Components to be in their own dedicated folder, another option for small apps is to keep Components flat (not in a dedicated folder). This adds up to four files to the existing folder, but also reduces the folder nesting. Be consistent. - - 虽然我们比较喜欢把组件放到它自己独立的目录里面,但是对于很小应用来说,另一个选项是保持平面化结构(不在自己独立的目录里)。这样我们添加最多四个文件到一个已有的目录,但是同时减少的目录的嵌套。保持前后一致就好。 - -a(href="#toc") Back to top - -a(href="#toc") 回到顶部 - - -.l-main-section -:marked - ### Shared Folder - ### 共享目录 - #### Style 04-07 - #### 风格04-07 - -.s-rule.do - :marked - **Do** put all shared files within a component feature in a `shared` folder. - - **坚持**在单个特性范围内,把所有共享的文件放到`shared`目录。 - -.s-rule.consider - :marked - **Consider** creating a folder for each component including its `.ts`, `.html`, `.css` and `.spec` file. - - **考虑**为每个组件新建一个目录,保存它的`.ts`、`.html`、`.css`和`.spec` 文件。 - -.s-why - :marked - **Why?** Separates shared files from the components within a feature. - - **为何?**在一个特性范围内,分离出组件共享的文件。 - -.s-why.s-why-last - :marked - **Why?** Makes it easier to locate shared files within a component feature. - - **为何?**使得在一个特性范围内,更加易于定位共享文件。 - -.example-title Shared Folder 共享的目录 -.filetree - .file src - .children - .file app - .children - .file heroes - .children - .file hero - .children - .file ... - .file hero-list - .children - .file ... - .file shared - .children - .file hero-button - .children - .file ... - .file hero.model.ts - .file hero.service.ts|spec.ts - .file index.ts - .file heroes.component.ts|html|css|spec.ts - .file index.ts - .file shared - .children - .file exception.service.ts|spec.ts - .file index.ts - .file nav - .children - .file ... - .file app.component.ts|html|css|spec.ts - .file main.ts - .file index.html - .file ... -:marked - -a(href="#toc") Back to top - -a(href="#toc") 回到顶部 - -.l-main-section -:marked - ### Folders-by-Feature Structure - ### 根据特性划分的目录结构 - #### Style 04-08 - #### 风格04-08 - -.s-rule.do - :marked - **Do** create folders named for the feature they represent. - - **坚持**把目录的名字命名为它包含的特性名字。 - -.s-why - :marked - **Why?** A developer can locate the code, identify what each file represents at a glance, the structure is as flat as it can be, and there is no repetitive nor redundant names. - - **为何?**开发者能定位代码,一眼就能看出每个文件是干什么的,结构尽可能平面化,并且没有重复或多余的名字。 - -.s-why - :marked - **Why?** The LIFT guidelines are all covered. - - **为何?**遵循LIFT指导原则。 - -.s-why - :marked - **Why?** Helps reduce the app from becoming cluttered through organizing the content and keeping them aligned with the LIFT guidelines. - - **为何?**在管理应用内容时,帮助减少把程序结构弄得很杂乱的可能性,确保它们向LIFT指导原则看齐。 - -.s-why.s-why-last - :marked - **Why?** When there are a lot of files (e.g. 10+) locating them is easier with a consistent folder structures and more difficult in flat structures. - - **为何?**当有很多文件(10个以上)的时候,在一致的目录结构下面,比在平面化结构下面定位它们要容易得多。 - -:marked - Below is an example of a small app with folders per component. - - 下面是一个小应用使用单组件目录的例子。 - -.example-title Folders per Component 单组件目录 -.filetree - .file src - .children - .file app - .children - .file heroes - .children - .file hero - .children - .file ... - .file hero-list - .children - .file ... - .file shared - .children - .file ... - .file heroes.component.ts|html|css|spec.ts - .file index.ts + .file shared.module.ts + .file init-caps.pipe.ts|spec.ts + .file text-filter.component.ts|spec.ts + .file text-filter.service.ts|spec.ts .file villains .children .file villain @@ -1575,188 +1677,307 @@ a(href="#toc") 回到顶部 .children .file ... .file villains.component.ts|html|css|spec.ts - .file index.ts - .file shared - .children - .file nav - .children - .file ... - .file ... + .file villains.module.ts + .file villains-routing.module.ts .file app.component.ts|html|css|spec.ts + .file app.module.ts + .file app-routing.module.ts .file main.ts .file index.html .file ... :marked +.l-sub-section + :marked + While components in dedicated folder are widely preferred, + another option for small apps is to keep components flat (not in a dedicated folder). + This adds up to four files to the existing folder, but also reduces the folder nesting. + Whatever you choose, be consistent. + + 把组件放在专用目录中的方式广受欢迎,对于小型应用,还可以保持组件扁平化(而不是放在专用目录中)。 + 这样会把四个文件放在现有目录中,但是也会减少目录的嵌套。无论你如何选择,请保持一致。 + a(href="#toc") Back to top a(href="#toc") 回到顶部 + .l-main-section :marked - ### Layout Components - ### 布局组件 - #### Style 04-09 - #### 风格04-09 + ### Folders-by-Feature Structure + ### 按特性组织的目录结构 + #### Style 04-07 + #### 风格04-07 .s-rule.do :marked - **Do** put components that define the overall layout in a `shared` folder. + **Do** create folders named for the feature area they represent. - **坚持**把定义总体布局的组件放到`shared`目录。 - -.s-rule.do - :marked - **Do** put shared layout components in their own folder, under the `shared` folder. - - **坚持**把共享的布局组件放到`shared`目录下它自己的独立目录里。 + **坚持**根据特性区的名字创建目录。 .s-why :marked - **Why?** We need a place to host our layout for our app. Our navigation bar, footer, and other aspects of the app that are needed for the entire app. + **Why?** A developer can locate the code, identify what each file represents at a glance, the structure is as flat as it can be, and there is no repetitive nor redundant names. - **为何?**我们需要一个地方来存放应用程序的布局,比如导航条、页脚和其它整个应用中都需要的东西。 + **为何?**开发人员可以定位代码,扫一眼就能知道每个文件代表什么,目录尽可能保持扁平,既没有重复也没有多余的名字。 + +.s-why + :marked + **Why?** The LIFT guidelines are all covered. + + **为何?**LIFT原则中包含了所有这些。 + +.s-why + :marked + **Why?** Helps reduce the app from becoming cluttered through organizing the content and keeping them aligned with the LIFT guidelines. + + **为何?**通过精心组织内容并让它们遵循LIFT原则,可以避免应用变得杂乱无章。 + +.s-why + :marked + **Why?** When there are a lot of files (e.g. 10+), locating them is easier with a consistent folder structure and more difficult in a flat structure. + + **为何?**当有很多文件时(比如10个以上),在“专用目录”型结构中定位它们会比在扁平结构中更容易。 + +.s-rule.do + :marked + **Do** create an Angular module for each feature area. + + **坚持**为每个特性区创建一个Angular模块。 + +.s-why + :marked + **Why?** Angular modules make it easy to lazy load routable features. + + **为何?**Angular模块能让对可路由的特性进行延迟加载变得更容易。 .s-why.s-why-last :marked - **Why?** Organizes all layout in a consistent place re-used throughout the application. + **Why?** Angular modules make it easier to isolate, test, and re-use features. - **为何?**在前后一致的地方管理所有布局,在整个应用程序范围内重复使用。 + **为何?**Angular模块能让我们更容易隔离、测试盒复用特性。 -.example-title Folder for Layout Components 布局组件目录 -.filetree - .file src - .children - .file app - .children - .file heroes - .children - .file ... - .file shared - .children - .file nav - .children - .file index.ts - .file nav.component.ts|html|css|spec.ts - .file footer - .children - .file index.ts - .file footer.component.ts|html|css|spec.ts - .file index.ts - .file ... - .file app.component.ts|html|css|spec.ts - .file main.ts - .file index.html - .file ... +.file-tree-reference + a(href="#file-tree") Refer here to this Folder and File Structure example + + a(href="#file-tree") 点这里查看目录和文件结构的范例 + +a(href="#toc") Back to top + :marked + +a(href="#toc") 回到顶部 + +.l-main-section :marked + ### App Root Module + ### 应用的根模块 + #### Style 04-08 + #### 风格04-08 + +.s-rule.do + :marked + **Do** create an Angular module at the root of the application. + + **坚持**在应用的根部创建一个Angular模块。 + +.s-why + :marked + **Why?** Every app requires at least one Angular module. + + **为何?**每个应用都至少需要一个Angular模块。 + +.s-rule.consider + :marked + **Consider** naming the root module `app.module.ts`. + + **考虑**把根模块命名为`app.module.ts`。 + +.s-why.s-why-last + :marked + **Why?** Makes it easier to locate and identify the root module. + + **为何?**能让定位和识别根模块变得更容易。 + ++makeExample('style-guide/ts/04-08/app/app.module.ts', 'example', 'app/app.module.ts') +:marked + +a(href="#toc") Back to top + +.l-main-section +:marked + ### Feature Modules + ### 特性模块 + #### Style 04-09 + #### 风格04-09 +.s-rule.do + + :marked + **Do** create an Angular module for all distinct features in an application (e.g. `Heroes` feature). + + **坚持**为应用中的每个明显的特性创建一个Angular模块。 + +.s-rule.do + :marked + **Do** place the feature module in the same named folder as the feature area (.e.g `app/heroes`). + + **坚持**把特性模块放在与特性区同名的目录中(如`app/heroes`)。 + +.s-rule.do + :marked + **Do** name the feature module file reflecting the name of the feature area and folder (e.g. `app/heroes/heroes.module.ts`) + + **坚持**特性模块的名字应该能反映出特性区的名字和目录(如`app/heroes/heroes.module.ts`)。 + +.s-rule.do + :marked + **Do** name the feature module symbol reflecting the name of the feature area, folder, and file (e.g. `app/heroes/heroes.module.ts` defines `HeroesModule`) + + **坚持**特性模块的符号名应该能反映出特性区、目录和文件的名字(如在`app/heroes/heroes.module.ts`中定义`HeroesModule`)。 + +.s-why + :marked + **Why?** A feature module can expose or hide its implementation from other modules. + + **为何?** 特性模块可以对其它模块暴露或隐藏自己的实现。 + +.s-why + :marked + **Why?** A feature module identifies distinct sets of related components that comprise the feature area. + + **为何?**特性模块标记出组成该特性分区的相关组件集合。 + +.s-why + :marked + **Why?** A feature module can easily be routed to both eagerly and lazily. + + **为何?**特性模块能很容易的被路由器加载 —— 无论使用提前加载还是延迟加载的方式。 + +.s-why + :marked + **Why?** A feature module defines clear boundaries between specific functionality and other application features. + + **为何?**特性模块在特定的功能和其它应用特性之间定义了清晰的边界。 + +.s-why + :marked + **Why?** A feature module helps clarify and make it easier to assign development responsibilities to different teams. + + **为何?**特性模块帮助澄清开发职责,以便于把这些职责指派给不同的开发组。 + +.s-why.s-why-last + :marked + **Why?** A feature module can easily be isolated for testing. + + **为何?**特性模块易于隔离,以便测试。 a(href="#toc") Back to top a(href="#toc") 回到顶部 - .l-main-section :marked - ### Create and Import Barrels - ### 创建和导入封装桶 + ### Shared Feature Module + ### 共享特性模块 #### Style 04-10 #### 风格04-10 -.s-rule.consider +.s-rule.do :marked - **Consider** creating a file that imports, aggregates, and re-exports items. We call this technique a **barrel**. + **Do** create a feature module named `SharedModule` in a `shared` folder (e.g. `app/shared/shared.module.ts` defines `SharedModule`). - **考虑**新建一个文件,用来导入、归集和重新导出项目。该技巧被称作**封装桶**。 - -.s-rule.consider + **坚持**在`shared`目录中创建名叫`SharedModule`的特性模块(比如在`app/shared/shared.module.ts`中定义`SharedModule`)。 + +.s-rule.do :marked - **Consider** naming this barrel file `index.ts`. + **Do** put common components, directives and pipes that will be used throughout the application by other feature modules in the `SharedModule`, where those assets are expected to share a new instance of themselves (not singletons). - **考虑**把该封装桶文件命名为`index.ts`。 + **坚持**把可能被应用的其它特性模块使用的公共资产(如组件、指令和管道)放在`SharedModule`中,这些资产倾向于共享自己的新实例(而不是单例)。 + +.s-rule.do + :marked + **Do** import all modules required by the assets in the `SharedModule` (e.g. `CommonModule` and `FormsModule`). + **坚持**在`SharedModule`中导入所有模块都需要的资产(比如:`CommonModule`和`FormsModule`)。 .s-why :marked - **Why?** A barrel aggregates many imports into a single import. + **Why?** `SharedModule` will contain components, directives and pipes that may need features from another common module (e.g. `ngFor` in `CommonModule`). + + **为何?** `SharedModule`中包含的组件、指令和管道可能需要来自其它公共模块的特性(比如来自`CommonModule`中的`ngFor`指令)。 - **为何?**封装桶把多个导入合并成一个单独的导入。 +.s-rule.do + :marked + **Do** declare all components, directives, and pipes in the `SharedModule`. + + **坚持**在`SharedModule`中声明所有组件、指令和管道。 + +.s-rule.do + :marked + **Do** export all symbols from the `SharedModule` that other feature modules need to use. + + **坚持**从`SharedModule`中导出其它特性模块所需的全部符号。 .s-why :marked - **Why?** A barrel reduces the number of imports a file may need. + **Why?** `SharedModule` exists to make commonly used components, directives and pipes available for use in the templates of components in many other modules. + + **为何?** `SharedModule`的存在,能让常用的组件、指令和管道在很多其它模块的组件模板中都自动可用。 - **为何?**封装桶减少文件可能需要导入的数量。 +.s-rule.avoid + :marked + **Avoid** specifying app-wide singleton providers in a `SharedModule`. Intentional singletons are OK. Take care. + **避免**在`SharedModule`中指定应用级的单例服务提供商。但如果是故意设计的单例也可以,不过还是要小心。 + .s-why :marked - **Why?** A barrel provides a consistent pattern to import everything exported in the barrel from a folder. + **Why?** A lazy loaded feature module that imports that shared module will make its own copy of the service and likely have undesireable results. - **为何?** 封装通提供一致连贯的模式,用来导入从一个目录中的封装的所有导出的东西。 - -.s-why - :marked - **Why?** This is consistent with a pattern from Node, which imports the index.js|ts file from a folder. - - **为何?** 这是一个从Node沿袭的一致连贯模式,用来从一个目录导入index.js|ts。 + **为何?**延迟加载的特性模块如果导入了这个共享模块,就会创建一份自己的服务副本,这可能会导致意料之外的后果。 .s-why.s-why-last :marked - **Why?** A barrel shortens import statements. + **Why?** You don't want each module to have its own separate instance of singleton services. + Yet there is a real danger of that happening if the `SharedModule` provides a service. - **为何?**封装桶精简了导入声明。 + **为何?**对于单例服务,你是不会希望每个模块都有自己的一份单独实例的。 + 而如果`SharedModule`提供了一个服务,那就会发生这种情况。 -+makeTabs( - `style-guide/ts/04-10/app/shared/index.ts, - style-guide/ts/04-10/app/shared/filter-text/index.ts, - style-guide/ts/04-10/app/shared/modal/index.ts, - style-guide/ts/04-10/app/shared/nav/index.ts, - style-guide/ts/04-10/app/shared/spinner/index.ts, - style-guide/ts/04-10/app/shared/toast/index.ts`, - `example,,,,,`, - `app/shared/index.ts, - app/shared/filter-text/index.ts, - app/shared/modal/index.ts, - app/shared/nav/index.ts, - app/shared/spinner/index.ts, - app/shared/toast/index.ts`) -:marked - -.example-title Folder Barrels 封装桶目录 .filetree .file src .children .file app .children - .file dashboard - .children - .file ... - .file index.ts - .file heroes - .children - .file ... - .file index.ts .file shared .children - .file nav - .children - .file ... - .file index.ts - .file search - .children - .file ... - .file index.ts - .file ... - .file index.ts + .file shared.module.ts + .file init-caps.pipe.ts|spec.ts + .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 main.ts .file index.html .file ... :marked -+makeExample('style-guide/ts/04-10/app/heroes/heroes.component.avoid.ts', 'example', 'app/heroes/heroes.component.ts')(avoid=1) -:marked - -+makeExample('style-guide/ts/04-10/app/heroes/heroes.component.ts', 'example', 'app/heroes/heroes.component.ts') ++makeTabs( + `style-guide/ts/04-10/app/shared/shared.module.ts, + style-guide/ts/04-10/app/shared/init-caps.pipe.ts, + style-guide/ts/04-10/app/shared/filter-text/filter-text.component.ts, + style-guide/ts/04-10/app/shared/filter-text/filter-text.service.ts, + style-guide/ts/04-10/app/heroes/heroes.component.ts, + style-guide/ts/04-10/app/heroes/heroes.component.html, + `, + `,,,`, + `app/shared/shared.module.ts, + app/shared/init-caps.pipe.ts, + app/shared/filter-text/filter-text.component.ts, + app/shared/filter-text/filter-text.service.ts, + app/heroes/heroes.component.ts, + app/heroes/heroes.component.html, + `) :marked a(href="#toc") Back to top @@ -1766,25 +1987,210 @@ a(href="#toc") 回到顶部 .l-main-section :marked - ### Lazy Loaded Folders - ### 惰性加载目录 + ### Core Feature Module + ### 核心特性模块 #### Style 04-11 #### 风格04-11 - A distinct application feature or workflow may be *lazy loaded* or *loaded on demand* rather than when the application starts. - - 一个独特的应用程序特性或者工作流可能被**惰性加载**或**按需加载**,而非在应用程序启动时就全部加载。 .s-rule.do :marked - **Do** put the contents of lazy loaded features in a *lazy loaded folder*. A typical *lazy loaded folder* contains a *routing component*, its child components, and their related assets and modules. + **Do** collect single-use classes and hiding their gory details inside `CoreModule`. A simplified root `AppModule` imports `CoreModule` in its capacity as orchestrator of the application as a whole. - **坚持**把惰性加载特性的文件放到**惰性加载目录**。典型的*惰性加载目录*中包含*路由组件*、子级组件和相关的东西和模块。 + **坚持**把那些“只用一次”的类收集到`CoreModule`中,并且对外隐藏它们的实现细节。简化的`AppModule`会导入`CoreModule`,并且把它作为整个应用的总指挥。 + +.s-rule.do + :marked + **Do** create a feature module named `CoreModule` in a `core` folder (e.g. `app/core/core.module.ts` defines `CoreModule`). + + **坚持**在`core`目录下创建一个名叫`CoreModule`的特性模块(比如在`app/core/core.module.ts`中定义`CoreModule`)。 + +.s-rule.do + :marked + **Do** put a singleton service whose instance wil be shared throughout the application in the `CoreModule` (e.g. `ExceptionService` and `LoggerService`). + + **坚持**把一个要共享给整个应用的单例服务放进`CoreModule`中(比如`ExceptionService`和`LoggerService`)。 + +.s-rule.do + :marked + **Do** import all modules required by the assets in the `CoreModule` (e.g. `CommonModule` and `FormsModule`). + + **坚持**导入`CoreModule`中的资产所需要的全部模块(比如`CommonModule`和`FormsModule`)。 + +.s-why + :marked + **Why?** `CoreModule` provides one or more singleton services. Angular registers the providers with the app root injector, making a singleton instance of each service available to any component that needs them, whether that component is eagerly or lazily loaded. + + **为何?** `CoreModule`提供了一个或多个单例服务。Angular使用应用的根注入器注册这些服务提供商,让每个服务的这个单例对象对所有需要它们的组件都是可用的,而不用管该组件是通过立即加载还是延迟加载的方式加载的。 + +.s-why + :marked + **Why?** `CoreModule` will contain singleton services. When a lazy loaded module imports these, it will get a new instance and not the intended app-wide singleton. + + **为何?**`CoreModule`将包含一些单例服务。而如果延迟加载模块导入这些服务,它就会得到一个新实例,而不是所期望的全应用级单例。 + +.s-rule.do + :marked + **Do** gather application-wide, single use components in the `CoreModule`. + Import it once (in the `AppModule`) when the app starts and never import it anywhere else. (e.g. `NavComponent` and `SpinnerComponent`). + + **坚持**把应用级、只用一次的组件收集到`CoreModule`中。 + 只在应用启动时从`AppModule`中导入它一次,以后再也不要导入它(比如`NavComponent`和`SpinnerComponent`)。 + +.s-why + :marked + **Why?** Real world apps can have several single-use components (e.g., spinners, message toasts, and modal dialogs) that appear only in the `AppComponent` template. + They are not imported elsewhere so they're not shared in that sense. + Yet they're too big and messy to leave loose in the root folder. + + **为何?**真实世界中的应用会有很多只用一次的组件(比如:加载动画、消息浮层、模态框等),它们只会在`AppComponent`的模板中出现,而不会出现在其它地方,所以它们没有被共享的价值。 + 然而它们又太大了,放在根目录中就会显得乱七八糟的。 + +.s-rule.avoid + :marked + **Avoid** importing the `CoreModule` anywhere except in the `AppModule`. + + **避免**不要在`AppModule`之外的任何地方导入`CoreModule`。 + +.s-why + :marked + **Why?** A lazily loaded feature module that directly imports the `CoreModule` will make its own copy of services and likely have undesireable results. + + **为何?**如果延迟加载的特性模块直接导入`CoreModule`,就会创建它自己的服务副本,并导致意料之外的后果。 + +.s-why + :marked + **Why?** An eagerly loaded feature module already has access to the `AppModule`'s injector, and thus the `CoreModule`'s services. + + **为何?**立即加载的特性模块已经准备好了访问`AppModule`的注入器,因此也能取得`CoreModule`中的服务。 + +.s-rule.do + :marked + **Do** export all symbols that from the `CoreModule` that the `AppModule` will import and make available for other feature modules to use. + + **坚持**从`CoreModule`中导出所有符号,`AppModule`会导入它们,并让它们能在所有特性模块中可用。 + +.s-why + :marked + **Why?** `CoreModule` exists to make commonly used singleton services available for use in the many other modules. + + **为何?**`CoreModule`的存在就能让常用的单例服务在所有其它模块中可用。 .s-why.s-why-last :marked - **Why?** The folder makes it easy to identify and isolate the feature content. + **Why?** You wnat the entire app to use the one, singleton instance. + You don't want each module to have its own separate instance of singleton services. + Yet there is a real danger of that happening accidentally if the `CoreModule` provides a service. - **为何?**该文件夹易于识别和隔离特性内容。 + **为何?**你会希望整个应用都使用这个单例服务。 + 你不会希望每个模块都有这个单例服务的单独的实例。 + 然而如果`CoreModule`中提供了一个服务,就可能偶尔导致这种后果。 + + +.filetree + .file src + .children + .file app + .children + .file core + .children + .file core.module.ts + .file logger.service.ts|spec.ts + .file nav + .children + .file nav.component.ts|html|css|spec.ts + .file spinner + .children + .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 main.ts + .file index.html + .file ... +:marked + ++makeTabs( + ` + style-guide/ts/04-11/app/app.module.ts, + style-guide/ts/04-11/app/core/core.module.ts, + style-guide/ts/04-11/app/core/logger.service.ts, + style-guide/ts/04-11/app/core/nav/nav.component.ts, + style-guide/ts/04-11/app/core/nav/nav.component.html, + style-guide/ts/04-11/app/core/spinner/spinner.component.ts, + style-guide/ts/04-11/app/core/spinner/spinner.component.html, + style-guide/ts/04-11/app/core/spinner/spinner.service.ts + `, + `example,,,,,,,`, + ` + app/app.module.ts, + app/core/core.module.ts, + app/core/logger.service.ts, + app/core/nav/nav.component.ts, + app/core/nav/nav.component.html, + app/core/spinner/spinner.component.ts, + app/core/spinner/spinner.component.html, + app/core/spinner/spinner.service.ts + `) +:marked + +.l-sub-section + :marked + `AppModule` is a little smaller because many app/root classes have moved to other modules. + `AppModule` is stable because you will add future components and providers to other modules, not this one. + `AppModule` delegates to imported modules rather than doing work. + `AppModule` is focused on its main task, orchestrating the app as a whole. + + `AppModule`变得更小了,因为很多应用根部的类都被移到了其它模块中。 + `AppModule`变得稳定了,因为你将会往其它模块中添加特性组件和服务提供商,而不是这个`AppModule`。 + `AppModule`把工作委托给了导入的模块,而不是亲力亲为。 + `AppModule`聚焦在它自己的主要任务上:作为整个应用的总指挥。 + +a(href="#toc") Back to top + +a(href="#toc") 回到顶部 + + +.l-main-section +:marked + ### Prevent Reimport of Core Module + ### 防止多次导入`CoreModule` + #### Style 04-12 + #### 风格04-12 + + Only the root `AppModule` should import the `CoreModule`. + + 应该只有`AppModule`才能导入`CoreModule`。 + +.s-rule.do + :marked + **Do** guard against reimporting of `CoreModule` and fail fast by adding guard logic. + + **坚持**防范多次导入`CoreModule`,并通过添加守卫逻辑来尽快失败。 + +.s-why.s-why + :marked + **Why?** Guards against reimporting of the `CoreModule`. + + **为何?**守卫可以阻止对`CoreModule`的多次导入。 + +.s-why.s-why-last + :marked + **Why?** Guards against creating multiple instances of assets intended to be singletons. + + **为何?**守卫会禁止创建单例服务的多个实例。 + ++makeTabs( + ` + style-guide/ts/04-12/app/core/module-import-guard.ts, + style-guide/ts/04-12/app/core/core.module.ts + `, + `,`, + ` + app/core/module-import-guard, + app/core/core.module.ts + `) +:marked a(href="#toc") Back to top @@ -1840,25 +2246,27 @@ a(href="#toc") 回到顶部 .l-main-section :marked - ### Never Directly Import Lazy Loaded Folders - ### 决不直接导入惰性加载目录 + ### Lazy Loaded Folders + ### 延迟加载的目录 #### Style 04-13 - #### 风格04-13 + #### 样式04-13 + A distinct application feature or workflow may be *lazy loaded* or *loaded on demand* rather than when the application starts. + + 某些边界清晰的应用特性或工作流可以做成*延迟加载*或*按需加载*的,而不用总是随着应用启动。 -.s-rule.avoid +.s-rule.do :marked - **Avoid** allowing modules in sibling and parent folders to directly import a module in a *lazy loaded feature*. + **Do** put the contents of lazy loaded features in a *lazy loaded folder*. + A typical *lazy loaded folder* contains a *routing component*, its child components, and their related assets and modules. - **避免**允许兄弟或者父目录里的模块直接导入*惰性加载特性*模块。 + **坚持**把延迟加载特性下的内容放进*延迟加载目录*中。 + 典型的*延迟加载目录*包含*路由组件*及其子组件以及与它们有关的那些资产和模块。 .s-why.s-why-last :marked - **Why?** Directly importing a module loads it immediately when our intention is to load it on demand. - - **为何?**直接导入模块会立刻加载它,但是我们的原意是按需加载。 - -+makeExample('style-guide/ts/04-13/app/app.component.avoid.ts', 'example', 'app/app.component.ts')(avoid=1) -:marked + **Why?** The folder makes it easy to identify and isolate the feature content. + + **为何?**这种目录让标识和隔离这些特性内容变得更轻松。 a(href="#toc") Back to top @@ -1866,25 +2274,22 @@ a(href="#toc") 回到顶部 .l-main-section :marked - ### Lazy Loaded Folders May Import From a Parent - ### 惰性加载目录可以导入父级 + ### Never Directly Import Lazy Loaded Folders + ### 永远不要直接导入延迟加载的目录 #### Style 04-14 #### 样式04-14 -.s-rule.do +.s-rule.avoid :marked - **Do** allow lazy loaded modules to import a module from a parent folder. + **Avoid** allowing modules in sibling and parent folders to directly import a module in a *lazy loaded feature*. - **坚持**允许惰性加载模块导入父级目录的模块。 + **避免**让兄弟模块和父模块直接导入*延迟加载特性*中的模块。 .s-why.s-why-last :marked - **Why?** A parent module has already been loaded by the time the lazy loaded module imports it. + **Why?** Directly importing and using a module will load it immediately when the intention is to load it on demand. - **为何?**在惰性加载模块导入父级模块的时候,父级模块早已经被加载了。 - -+makeExample('style-guide/ts/04-14/app/heroes/heroes.component.ts', 'example', 'app/heroes/heroes.component.ts') -:marked + **为何?**直接导入并使用此模块会立即加载它,而我们原本的设计意图是按需加载它。 a(href="#toc") Back to top @@ -1919,16 +2324,16 @@ a(href="#toc") 回到顶部 :marked ## Components - ### Components Selector Naming + ### Component Selector Naming ### 组件选择器命名 #### Style 05-02 #### 风格05-02 .s-rule.do :marked - **Do** use `kebab-case` for naming the element selectors of our components. + **Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components. - **坚持**使用`烤串命名法(中线命名法)`来命名组件的元素选择器。 + **坚持**使用*中线(dashed)命名法*或*烤串(kebab)命名法*来命名组件中的元素选择器。 .s-why.s-why-last :marked @@ -1960,21 +2365,23 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** define Components as elements via the selector. + **Do** define components as elements via the selector. - **坚持**通过选择器来定义充当元素的组件。 + **坚持**通过选择器把组件定义为元素。 .s-why :marked - **Why?** Components have templates containing HTML and optional Angular template syntax. They are most associated with putting content on a page, and thus are more closely aligned with elements. + **Why?** components have templates containing HTML and optional Angular template syntax. They are most associated with putting content on a page, and thus are more closely aligned with elements. - **为何?**组件有模板,包含HTML和可能有的Angular模板语法。它们大多数都是用来在页面上面放置内容的,所以与元素更加类似。 + **为何?**组件有很多包含HTML以及可选Angular模板语法的模板。它们的功能多数都与把内容放进页面有关,而这和HTML元素的设计意图很相似。 .s-why :marked - **Why?** Components are derived from Directives, and thus their selectors can be elements, attributes, or other selectors. Defining the selector as an element provides consistency for components that represent content with a template. + **Why?** A component represents a visual element on the page. + Defining the selector as an HTML element tag is consistent with native HTML elements and WebComponents. - **为何?**组件是从指令派生出来的,所以它们的选择器可以是元素、特性或者其它选择器。把选择器作为元素来定义,统一了通过模块提供内容的组件。 + **为何?**组件表示页面上的可视元素。 + 把该选择器定义成HTML元素标签可以与原生HTML和WebComponent保持一致。 .s-why.s-why-last :marked @@ -2015,16 +2422,16 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** name the template file `[component-name].component.html`, where [component-name] is our component name. + **Do** name the template file `[component-name].component.html`, where [component-name] is the component name. - **坚持**当组件名字为[component-name]的时候,命名它的模板为`[component-name].component.html`。 + **坚持**把模板文件命名为`[component-name].component.html`,这里的[component-name]就是组件名。 .s-rule.do :marked - **Do** name the style file `[component-name].component.css`, where [component-name] is our component name. + **Do** name the style file `[component-name].component.css`, where [component-name] is the component name. + + **坚持**把样式文件命名为`[component-name].component.css`,这里的[component-name]就是组件名。 - **坚持**当组件名字为[component-name]时,命名它的样式为`[component-name].component.css`。 - .s-why :marked **Why?** Syntax hints for inline templates in (*.js and *.ts) code files are not supported by some editors. @@ -2082,9 +2489,15 @@ a(href="#toc") 回到顶部 .s-why :marked - **Why?** If we ever need to rename the property or event name associated to [`@Input`](https://angular.io/docs/ts/latest/api/core/index/Input-var.html) or [`@Output`](https://angular.io/docs/ts/latest/api/core/index/Output-var.html) we can modify it on a single place. + **Why?** If you ever need to rename the property or event name associated to + [`@Input`](https://angular.io/docs/ts/latest/api/core/index/Input-var.html) or + [`@Output`](https://angular.io/docs/ts/latest/api/core/index/Output-var.html) + you can modify it on a single place. - **为何?**如果我们需要重命名[`@Input`](https://angular.io/docs/ts/latest/api/core/Input-var.html) 或 [`@Output`](https://angular.io/docs/ts/latest/api/core/Output-var.html)关的属性或者事件,我们可以在一个地方修改。 + **为何?**如果你永远都不用对关联到 + [`@Input`](https://angular.io/docs/ts/latest/api/core/index/Input-var.html)或 + [`@Output`](https://angular.io/docs/ts/latest/api/core/index/Output-var.html)的属性或事件进行改名, + 那么你可以只在一处地方修改它。 .s-why :marked @@ -2167,9 +2580,10 @@ a(href="#toc") 回到顶部 .s-why.s-why-last :marked - **Why?** Placing members in a consistent sequence makes it easy to read and helps we instantly identify which members of the component serve which purpose. + **Why?** Placing members in a consistent sequence makes it easy to read and + helps instantly identify which members of the component serve which purpose. - **为何?**使用一致的顺序放置成员,可以增加阅读性,并帮助我们立刻识别出组件里面哪个成员是干什么的。 + **为何?**把类的成员按照统一的顺序排列,可以让它们更易于阅读,这能帮我们立即识别出组件的哪个成员服务于何种目的(比如是实现还是接口)。 +makeExample('style-guide/ts/05-14/app/shared/toast/toast.component.avoid.ts', 'example', 'app/shared/toast/toast.component.ts')(avoid=1) :marked @@ -2250,9 +2664,9 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** name our event handler methods with the prefix `on` followed by the event name. + **Do** name event handler methods with the prefix `on` followed by the event name. - **坚持**命名事件处理方法时,带前缀`on`,紧跟事件名字。 + **坚持**把事件处理器方法命名为`on`前缀之后紧跟着事件名。 .s-why :marked @@ -2292,15 +2706,15 @@ a(href="#toc") 回到顶部 .s-rule.do :marked - **Do** put presentation logic in the Component class, and not in the template. + **Do** put presentation logic in the component class, and not in the template. - **坚持**把展示逻辑放到组件类里,而非模板里。 + **坚持**把表现层逻辑放进组件类中,而不要放在模板里。 .s-why :marked - **Why?** Logic will be contained in one place (the Component class) instead of being spread in two places. + **Why?** Logic will be contained in one place (the component class) instead of being spread in two places. - **为何?**所有逻辑都被放置到一个地方(组件类),而不被分离到两个地方。 + **为何?**逻辑应该只出现在一个地方(组件类里)而不应分散在两个地方。 .s-why.s-why-last :marked @@ -2370,28 +2784,42 @@ a(href="#toc") 回到顶部 #### Style 06-03 #### 风格06-03 +.s-rule.consider + :marked + **Consider** preferring the `@HostListener` and `@HostBinding` to the + `host` property of the `@Directive` and `@Component` decorators. + + **考虑**优先使用`@HostListener`和`@HostBinding`,而不是`@Directive`和`@Component`装饰器的`host`属性。 + .s-rule.do :marked - **Do** use @HostListener and @HostBinding instead of the host property of the @Directive and @Component decorators: + **Do** be consistent in your choice. - **坚持**使用@HostListener和@HostBinding,而非@Directive和@Component装饰器的宿主属性。 - -.s-why - :marked - **Why?** The property or method name associated with @HostBinding or respectively @HostListener should be modified only in a single place - in the directive's class. In contrast if we use host we need to modify both the property declaration inside the controller, and the metadata associated to the directive. - - **为何?**与属性或方法名字相关联的@HostBinding或者@HostListener应该只在一个地方被修改:在指令的类里。反过来,如果我们使用宿主属性,我们需要在控制器内修改属性声明,然后在指令相关的元数据里修改。 + **坚持**让你的选择保持一致。 .s-why.s-why-last :marked - **Why?** The metadata declaration attached to the directive is shorter and thus more readable. + **Why?** The property associated with `@HostBinding` or the method associated with `@HostListener` + can be modified only in a single place - in the directive's class. + If you use the `host` metadata property, you must modify both the property declaration inside the controller, + and the metadata associated with the directive. - **为何?**指令附带的元数据声明会简短一些,易于阅读。 + **为何?**对于关联到`@HostBinding`的属性或关联到`@HostListener`的方法,要改名时只要在指令类中修改一次就行了。 + 如果使用元数据属性`host`,你就得在组件类中修改属性声明的同时修改相关的元数据。 -+makeExample('style-guide/ts/06-03/app/shared/validator.directive.avoid.ts', 'example', 'app/shared/validator.directive.ts')(avoid=1) ++makeExample('style-guide/ts/06-03/app/shared/validator.directive.ts', '', 'app/shared/validator.directive.ts') :marked + Compare with the less preferred `host` metadata alternative. + + 与不推荐的方式(`host`元数据)比较一下。 -+makeExample('style-guide/ts/06-03/app/shared/validator.directive.ts', 'example', 'app/shared/validator.directive.ts') +.s-why.s-why-last + :marked + **Why?** The `host` metadata is only one term to remember and doesn't require extra ES imports. + + **为何?**`host`元数据只是一个便于记忆的名字而已,并不需要额外的ES导入。 + ++makeExample('style-guide/ts/06-03/app/shared/validator2.directive.ts', '', 'app/shared/validator2.directive.ts') :marked a(href="#toc") Back to top @@ -2403,8 +2831,8 @@ a(href="#toc") 回到顶部 ## Services ## 服务 - ### Services are Singletons in Same Injector - ### 在同一个注入器内,服务是单例 + ### Services are Singletons within an Injector + ### 在同一个注入器中,服务总是单例的 #### Style 07-01 #### 风格07-01 @@ -2460,9 +2888,9 @@ a(href="#toc") 回到顶部 .s-why.s-why-last :marked - **Why?** When a service has multiple responsibilities, every Component or Service that injects it now carries the weight of them all. + **Why?** When a service has multiple responsibilities, every component or service that injects it now carries the weight of them all. - **为何?**当服务有多个职责时,每个注入它的组件或者服务都会被迫承担它们的(多个职责)所有的重量。 + **为何?**当某个服务有多个职责时,每个注入它的组件或服务都会承担这些职责的全部开销。 a(href="#toc") Back to top @@ -2531,9 +2959,9 @@ a(href="#toc") 回到顶部 .s-why :marked - **Why?** The Angular DI mechanism resolves all the dependencies of our services based on their types declared with the services' constructors. + **Why?** The Angular DI mechanism resolves all dependencies of services based on their types declared with the services' constructors. - **为何?**Angular的依赖注入机制,是根据在服务的构造函数里面的类型的声明,来解析所有服务的依赖的。 + **为何?**Angular的DI机制会基于在服务的构造函数中所声明的类型来解析这些服务的依赖。 .s-why.s-why-last :marked @@ -2622,9 +3050,11 @@ a(href="#toc") Back to top .s-why.s-why-last :marked - **Why?** We avoid unintentionally not calling the hook if we misspell the method. - - **为何?**避免在方法名字拼写错误时,造成无意间没有调用钩子的可能。 + **Why?** Strongly-typed method signatures. + The compiler and editor can call out misspellings. + + **为何?**如果使用强类型的方法签名,那么编译器和编辑器可以帮你揪出拼写错误。 + +makeExample('style-guide/ts/09-01/app/heroes/shared/hero-button/hero-button.component.avoid.ts', 'example', 'app/heroes/shared/hero-button/hero-button.component.ts')(avoid=1) :marked @@ -2633,6 +3063,8 @@ a(href="#toc") Back to top a(href="#toc") Back to top +a(href="#toc") 回到顶部 + .l-main-section :marked ## Appendix diff --git a/public/docs/ts/latest/guide/upgrade.jade b/public/docs/ts/latest/guide/upgrade.jade index eb12a95617..dd9f4bf742 100644 --- a/public/docs/ts/latest/guide/upgrade.jade +++ b/public/docs/ts/latest/guide/upgrade.jade @@ -1,12 +1,5 @@ include ../_util-fns -.alert.is-important - :marked - This guide is still in the process of being updated to RC5 and it's samples - may not work correctly. - - 我们正在为RC5更新本指南,目前本指南中的例子暂时不会正常运行。 - :marked Having an existing Angular 1 application doesn't mean that we can't begin enjoying everything Angular 2 has to offer. That's because Angular 2 @@ -43,8 +36,8 @@ include ../_util-fns 1. [Preparation](#preparation) 1. [准备工作](#preparation) - 1. [Following The Angular Style Guide](#following-the-angular-style-guide) - 1. [遵循Angular风格指南](#following-the-angular-style-guide) + 1. [Follow the Angular Style Guide](#follow-the-angular-style-guide) + 1. [遵循Angular风格指南](#follow-the-angular-style-guide) 2. [Using a Module Loader](#using-a-module-loader) 2. [使用模块加载器](#using-a-module-loader) 3. [Migrating to TypeScript](#migrating-to-typescript) @@ -55,7 +48,7 @@ include ../_util-fns 2. [通过升级适配器进行升级](#upgrading-with-the-upgrade-adapter) 1. [How The Upgrade Adapter Works](#how-the-upgrade-adapter-works) 1. [如何升级适配器](#how-the-upgrade-adapter-works) - 2. [Bootstrapping Hybrid Angular 1+2 Applications](#bootstrapping-hybrid-angular-1-2-applications) + 2. [Bootstrapping hybrid Angular 1+2 Applications](#bootstrapping-hybrid-angular-1-2-applications) 2. [引导Angular 1和2的混合(hybrid)应用](#bootstrapping-hybrid-angular-1-2-applications) 3. [Using Angular 2 Components from Angular 1 Code](#using-angular-2-components-from-angular-1-code) 3. [从Angular 1的代码中使用Angular 2的组件](#using-angular-2-components-from-angular-1-code) @@ -75,7 +68,7 @@ include ../_util-fns 1. [切换到TypeScript](#switching-to-typescript) 2. [Installing Angular 2](#installing-angular-2) 2. [安装Angular 2](#installing-angular-2) - 3. [Bootstrapping A Hybrid 1+2 PhoneCat](#bootstrapping-a-hybrid-1-2-phonecat) + 3. [Bootstrapping a hybrid 1+2 PhoneCat](#bootstrapping-a-hybrid-1-2-phonecat) 3. [引导Angular 1+2的混合版PhoneCat](#bootstrapping-a-hybrid-1-2-phonecat) 4. [Upgrading the Phone service](#upgrading-the-phone-service) 4. [升级Phone服务](#upgrading-the-phone-service) @@ -100,7 +93,7 @@ include ../_util-fns Angular 1应用程序的组织方式有很多种。当我们想把它们升级到Angular 2的时候, 有些做起来会比其它的更容易些。即使在我们开始升级之前,也有一些关键的技术和模式可以让我们将来升级时更轻松。 - ## Following The Angular Style Guide + ## Follow the Angular Style Guide ## 遵循Angular风格指南 The [Angular 1 Style Guide](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#single-responsibility) @@ -640,6 +633,40 @@ figure.image-display 相应的,当我们把Angular 1的组件升级给Angular 2使用时,在这个组件型指令的`scope`(或`bindToController`)中定义的所有绑定, 都将被挂钩到Angular 2的变更检测体系中。它们将和标准的Angular 2输入属性被同等对待,并当它们发生变化时设置回scope(或控制器)上。 + ## Using the Upgrade Adapter with Angular 2 _NgModules_ + + ## 通过Angular 2的*NgModule*来使用升级适配器 + + Both Angular 1 and Angular 2 have their own concept of modules + to help organize an application into cohesive blocks of funcionality. + + Angular 1还是Angular 2都有自己的模块概念,来帮你我们把应用组织成一些紧密相关的功能块。 + + Their details are quite different in architecture and implementation. + In Angular 1, you add Angular assets to the `angular.module` property. + In Angular 2, you create one or more classes adorned with an `NgModule` decorator + that describes Angular assets in metadata. The differences blossom from there. + + 它们在架构和实现的细节上有着显著的不同。 + 在Angular 1中,我们会把Angular 1的资源添加到`angular.module`属性上。 + 在Angular 2中,我们会创建一个或多个带有`NgModule`装饰器的类,这些装饰器用来在元数据中描述Angular资源。差异主要来自这里。 + + In a hybrid application we run both versions of Angular at the same time. + That means that we need at least one module each from both Angular 1 and Angular 2. + We will give the Angular 2 module to the `UpgradeAdapter` while we use the + Angular 1 module for bootstrapping. Let's see how. + + 在混合式应用中,我们同时运行了两个版本的Angular。 + 这意味着我们至少需要Angular 1和Angular 2各提供一个模块。 + 当我们使用Angular 1的模块进行引导时,就得把Anuglar 2的模块传给`UpgradeAdapter`。我们来看看怎么做。 + +.l-sub-section + :marked + Learn more about Angular 2 modules at the [NgModule guide](ngmodule.html). + + 要了解Angular 2模块的更多信息,请参阅[Angular模块](ngmodule.html)页。 + +:marked ## Bootstrapping Hybrid Angular 1+2 Applications ## 引导Angular 1+2的混合式应用程序 @@ -678,38 +705,44 @@ figure.image-display +makeExample('upgrade-adapter/ts/app/1-bootstrap/app.module.ts', 'bootstrap') :marked - To then switch the application into hybrid mode, we must first - install Angular 2 to the project. Follow the instructions in - [the QuickStart](../quickstart.html) for some pointers on this. - When we have Angular 2 installed, we can import and instantiate - the `UpgradeAdapter`, and then call its `bootstrap` method. It - is designed to take the exact same arguments as - [angular.bootstrap](https://docs.angularjs.org/api/ng/function/angular.bootstrap) - so that it is easy to make the switch: + Now introduce Angular 2 to the project. Inspired by instructions in + [the QuickStart](../quickstart.html), you can selectively copy in material from the + QuickStart github repository. + + 现在,把Angular 2引入项目中。根据[“快速起步”](../quickstart.html)中的指导,你可以有选择的从“快速起步”的Github仓库中拷贝素材进来。 - 要把这个应用切换到混合模式,我们得先把Angular 2安装到项目中。遵循[“快速起步”](../quickstart.html)中给出的步骤完成它。 - 安装完Angular 2之后,我们可以导入和实例化`UpgradeAdapter`类,然后调用它的`bootstrap`方法。 - 它被设计成接受与[angular.bootstrap](https://docs.angularjs.org/api/ng/function/angular.bootstrap)完全相同的参数。 - 所以,做这种切换很简单: + Next, create an `app.module.ts` file and add the following `NgModule` class: + + 接下来,创建一个`app.module.ts`文件,并添加下列`NgModule`类: + ++makeExample('upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts', 'ngmodule') + +:marked + This bare minimum `NgModule` imports `BrowserModule`, the module every Angular browser-based app must have. + + 这个最小化的`NgModule`导入了`BrowserModule`,该模块是每个基于浏览器的Angular应用都必须具备的。 + + Import and instantiate the `UpgradeAdapter` with the new `AppModule` and call its `bootstrap` method. + That method takes the exact same arguments as [angular.bootstrap](https://docs.angularjs.org/api/ng/function/angular.bootstrap): + + 用新的`AppModule`来导入和实例化`UpgradeAdapter`类,并调用它的`bootstrap`方法。 + 该方法被设计成接受与[angular.bootstrap](https://docs.angularjs.org/api/ng/function/angular.bootstrap)完全相同的参数: +makeExample('upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts', 'bootstrap') :marked - At this point we'll be running a hybrid Angular 1+2 application! All the - existing Angular 1 code will work as it always did, but we are now ready - to run Angular 2 code as well. + Congratulations! You're running a hybrid Angular 1+2 application! The + existing Angular 1 code works as before _and_ you're ready to run Angular 2 code. - 这时,我们就要开始运行Angular 1+2的混合式应用程序了!所有现存的Angular 1代码会像以前一样正常工作,但是我们现在也同样可以运行Angular 2代码了。 + 恭喜!我们就要开始运行Angular 1+2的混合式应用程序了!所有现存的Angular 1代码会像以前一样正常工作,但是我们现在也同样可以运行Angular 2代码了。 .alert.is-helpful :marked - One notable difference between `angular.bootstrap` and - `upgradeAdapter.bootstrap` is that the latter works *asynchronously*. - This means that we cannot assume that the application has been instantiated - immediately after the bootstrap call returns. + Note that, unlike `angular.bootstrap`, the `upgradeAdapter.bootstrap` runs *asynchronously*. + The application is not launched immediately. Some time must pass after the bootstrap call returns. - 在`angular.bootstrap`和`upgradeAdapter.bootstrap`之间一个显著的不同点是:后者是*异步*工作的。 - 这意味着当这次`bootstrap`调用刚刚返回时,我们不能假设应用程序已经被初始化过了。 + 注意,在`angular.bootstrap`和`upgradeAdapter.bootstrap`之间有一个显著的不同点:后者是*异步*工作的。 + 该应用不是立即启动的。有时必须在这次bootstrap调用返回后才能传入。 :marked As we begin to migrate components to Angular 2, we'll be using the @@ -762,7 +795,19 @@ figure +makeExample('upgrade-adapter/ts/app/downgrade-static/app.module.ts', 'downgradecomponent') :marked - What we have here is an Angular 1 directive called `heroDetail`, which we can + Because `HeroDetailComponent` is an Angular 2 component, we must also add it to the `declarations` in the `AppModule`. + + 由于`HeroDetailComponent`是一个Angular 2组件,所以我们必须同时把它加入`AppModule`的`declarations`字段中。 + ++makeExample('upgrade-adapter/ts/app/downgrade-static/app.module.ts', 'ngmodule') +.l-sub-section + :marked + All Angular 2 components, directives and pipes must be declared in an NgModule. + + 所有Angular 2组件、指令和管道都必须声明在NgModule中。 + +:marked + The net resulit is an Angular 1 directive called `heroDetail`, that we can use like any other directive in our Angular 1 templates. 这里我们得到的是一个叫做`heroDetail`的Angular 1指令,我们可以像用其它指令一样把它用在Angular 1模板中。 @@ -772,12 +817,13 @@ figure .alert.is-helpful :marked - Note that since Angular 1 directives are matched based on their name, - *the selector metadata of the Angular 2 component is not used in Angular 1*. - It is matched as an element directive (`restrict: 'E'`) called `heroDetail`. - - 注意,由于Angular 1的指令是基于它们的名字进行匹配的,*Angular 2组件元数据中的`selector`不会被用在Angular 1中*。 - 它会像一个名叫`heroDetail`的元素型指令(`restrict: 'E'`)一样被匹配。 + Note that this Angular 1 is an element directive (`restrict: 'E'`) called `heroDetail`. + An Angular 1 element directive is matched based on its _name_. + *The `selector` metadata of the downgraded Angular 2 component is ignored.* + + 注意,它在Angular 1中是一个名叫`heroDetail`的元素型指令(`restrict: 'E'`)。 + Angular 1的元素型指令是基于它的*名字*匹配的。 + *Angular 2组件中的`selector`元数据,在降级后的版本中会被忽略。* :marked Most components are not quite this simple, of course. Many of them @@ -881,15 +927,14 @@ figure :marked We can *upgrade* this component to Angular 2 using the `UpgradeAdapter`'s `upgradeNg1Component` method. It takes the name of an Angular 1 component - directive and returns an Angular 2 **component class**. When we then - want to use it from an Angular 2 component, we list it the in the `directives` - metadata of the component and then just use it in the Angular 2 template: + directive and returns an Angular 2 **component class**. + Declare it in an `NgModule` as with other Angular 2 components: 我们可以使用`UpgradeAdapter`的`upgradeNg1Component`方法来把这个组件*升级*到Angular 2。 它接受Angular 1组件型指令的名字,并返回一个Angular 2**组件类**。 - 当我们以后想从Angular 2组件中用它时,只要把它列在组件的`directives`元数据中,然后直接在Angular 2模板中用它就可以了: + 像其它Angular 2组件一样,请把它声明在`NgModule`中: -+makeExample('upgrade-adapter/ts/app/upgrade-static/container.component.ts', null, 'container.component.ts') ++makeExample('upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts', 'heroupgrade', 'app.module.ts') .alert.is-helpful :marked @@ -1126,25 +1171,19 @@ figure +makeExample('upgrade-adapter/ts/app/2-to-1-providers/heroes.ts', null, 'heroes.ts') :marked - We can again use the `UpgradeAdapter` for this, but first we need to register `Heroes` - to the Angular 2 injector itself. In a pure Angular 2 application we would do this - when we bootstrap the app, as described in the [dependency injection guide](dependency-injection.html#!#providers). - But since hybrid applications are bootstrapped using the `UpgradeAdapter`, we also - need to register our Angular 2 providers using `UpgradeAdapter`. It has a method - called `addProvider` for this purpose. + Again, as with Angular 2 components, register the provider with the `NgModule` by adding it to the module's `providers` list. + + 仿照Angular 2组件,我们通过把该提供商加入`NgModule`的`providers`列表中来注册它。 - 我们又能使用`UpgradeAdapter`处理它了,但首先我们需要把`Heroes`服务注册到Angular 2自身的注入器。 - 在纯Angular 2应用中,我们会在引导应用时这么做,就像[依赖注入指南](dependency-injection.html#!#providers)中描述的那样。 - 但是因为混合式应用是使用`UpgradeAdapter`引导的,所以我们还得用`UpgradeAdapter`注册Angular 2的提供商。 - 它有一个`addProvider`方法就是用来做这个的。 ++makeExample('upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts', 'ngmodule', 'app.module.ts') - Once we've registered the Angular 2 provider, we can turn `Heroes` into an *Angular 1 - factory function* using `upgradeAdapter.downgradeNg2Provider()`. We can - then plug the factory into an Angular 1 module, at which point we also choose what the - name of the dependency will be in Angular 1: +:marked + Now wrap the Angular 2 `Heroes` in an *Angular 1 factory function* using `upgradeAdapter.downgradeNg2Provider()`. + and plug the factory into an Angular 1 module. + The name of the Angular 1 dependency is up to you: - 一旦我们注册了Angular 2的提供商,就能用`upgradeAdapter.downgradeNg2Provider()`把`Heroes`转变成一个*Angular 1的工厂函数*。 - 然后我们就能把这个工厂插入到Angular 1模块中,那时,我们可以选择该依赖要在Angular 1中用的名字: + 现在,我们使用`upgradeAdapter.downgradeNg2Provider()`来把Angular 2的`Heroes`包装成*Angular 1的工厂函数*,并把这个工厂注册进Angular 1的模块中。 + 依赖在Angular 1中的名字你可以自己定: +makeExample('upgrade-adapter/ts/app/2-to-1-providers/app.module.ts', 'register', 'app.module.ts') @@ -1569,7 +1608,7 @@ code-example(format=""). 把`app/index.html`移入项目的根目录,然后把`package.json`中的开发服务器根目录也指向项目的根目录,而不再是`app`目录: -+makeJson('upgrade-phonecat-2-hybrid/ts/package.ng1.json', {paths: 'scripts.start'}, 'package.json') ++makeJson('upgrade-phonecat-2-hybrid/ts/package.ng1.json', {paths: 'scripts.start'}, 'package.json (start script)') :marked Now we're able to serve everything from the project root to the web browser. But we do *not* @@ -1602,7 +1641,31 @@ code-example(format=""). +makeExample('upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js', 'paths', 'systemjs.config.js') :marked - ## Bootstrapping A Hybrid 1+2 PhoneCat + ## Creating the _AppModule_ + + ## 创建*AppModule* + + Now create the root `NgModule` class called `AppModule`. + There is already a file named `app.module.ts` that holds the Angular 1 module. + Rename it to `app.module.ng1.ts` and update the corresponding script name in the `index.html` as well. + The file contents remain: + + 现在,创建一个名叫`AppModule`的根`NgModule`类。 + 我们已经有了一个名叫`app.module.ts`的文件,其中存放着Angular 1的模块。 + 把它改名为`app.module.ng1.ts`,同时也要在`index.html`中更新对应的脚本名。 + 文件的内容保留: + ++makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ng1.ts', null, 'app.module.ng1.ts') + +:marked + Now create a new `app.module.ts` with the minimum `NgModule` class: + + 然后创建一个新的`app.module.ts`文件,其中是一个最小化的`NgModule`类: + ++makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'bare', 'app.module.ts') + +:marked + ## Bootstrapping a hybrid 1+2 PhoneCat ## 引导PhoneCat的1+2混合式应用 What we'll do next is bootstrap the application as a *hybrid application* @@ -1676,37 +1739,19 @@ code-example(format=""). * 把一台电话的详情加载到电话详情组件中。 We can replace this implementation with an Angular 2 service class, while - keeping our controllers in Angular 1 land. In the new version we'll just use - the `Http` service from Angular 2 instead of ngResource. - + keeping our controllers in Angular 1 land. + 我们可以用Angular 2的服务类来替换这个实现,而把控制器继续留在Angular 1的地盘上。 - 在新版本中,我们将用来自Angular 2的`Http`服务代替`ngResource`。 + + In the new version, we import the Angular 2 HTTP module and call its `Http` service instead of `ngResource`. - Before the `Http` service is available for injection, we need to register - it into our application's dependency injector. We should import the `HTTP_PROVIDERS` - constant in `main.ts`: + 在这个新版本中,我们导入了Angular 2的HTTP模块,并且用它的`Http`服务替换掉`NgResource`。 - 要让`Http`服务在注入时可用,我们得先把它注册进我们应用程序的依赖注入器中。我们要把`HTTP_PROVIDERS`常量导入到`app.module.ts`中: + Re-open the `app.module.ts` file, import and add `HttpModule` to the `imports` array of the `AppModule`: + + 再次打开`app.module.ts`文件,导入并把`HttpModule`添加到`AppModule`的`imports`数组中: -+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'import-http') - -:marked - In a regular Angular 2 application we would now pass `HTTP_PROVIDERS` into - the application bootstrap function. But we can't do that in a hybrid - application such as the one we're working on. That's because the `bootstrap` - method of `UpgradeAdapter` expects Angular 1 modules as dependencies, - not Angular 2 providers. - - 在标准的Angular 2应用中,我们可以把`HTTP_PROVIDERS`传给应用程序的`bootstrap`函数。 - 但是在混合式应用中我们不能这么做 —— 比如现在这个。这是因为`UpgradeAdapter`的`bootstrap`方法 - 希望以Angular 1模块作为依赖,而不是Angular 2提供商。 - - What we must do instead is register `HTTP_PROVIDERS` into the `UpgradeAdapter` - separately. It has a method called `addProvider` for that purpose: - - 这就是为什么我们必须单独把`HTTP_PROVIDERS`注册进`UpgradeAdapter`。为此,它提供了一个叫做`addProvider`的方法: - -+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'add-http') ++makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'httpmodule', 'app.module.ts') :marked Now we're ready to upgrade the Phone service itself. We replace the ngResource-based @@ -1714,7 +1759,7 @@ code-example(format=""). 现在,我们已经准备好了升级`Phones`服务本身。我们将为`phone.service.ts`文件中基于ngResource的服务加上`@Injectable`装饰器: -+makeExample('upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts', 'classdef', 'app/core/phone/phone.service.ts') ++makeExample('upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts', 'classdef', 'app/core/phone/phone.service.ts (skeleton)')(format='.') :marked The `@Injectable` decorator will attach some dependency injection metadata @@ -1745,7 +1790,7 @@ code-example(format=""). 该方法现在返回一个`Phone`类型或`Phone[]`类型的可观察对象(Observable)。 这是一个我们从未用过的类型,因此我们得为它新增一个简单的接口: -+makeExample('upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts', 'phonedata-interface', 'app/core/phone/phone.service.ts') ++makeExample('upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts', 'phonedata-interface', 'app/core/phone/phone.service.ts (interface)')(format='.') :marked Here's the full, final code for the service: @@ -1758,42 +1803,26 @@ code-example(format=""). Notice that we're importing the `map` operator of the RxJS `Observable` separately. We need to do this for all RxJS operators that we want to use, since Angular 2 does not load all of them by default. - + 注意,我们单独导入了RxJS `Observable`中的`map`操作符。 我们需要对想用的所有RxJS操作符这么做,因为Angular 2默认不会加载所有RxJS操作符。 - The new `Phone` service now has the same features that the original, ngResource based - service did. Now we just need to register the new service into the application, so that - our Angular 1 components will be able to use it. - - 这个新的`Phones`服务现在有了和原来基于`ngResource`的服务相同的特性。 - 现在只要把这个新服务注册进应用程序,我们的Angular 1控制器就能使用它了。 - + The new `Phone` service has the same features as the original, `ngResource`-based service. + Because it's an Angular 2 service, we register it with the `NgModule` providers: + + 这个新的`Phone`服务具有和老的基于`ngResource`的服务相同的特性。 + 因为它是Angular 2服务,我们通过`NgModule`的`providers`数组来注册它: ++makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'phone', 'app.module.ts') +:marked `UpgradeAdapter` has a `downgradeNg2Provider` method for the purpose of making - Angular 2 services available to Angular 1 code. We can use it to plug in our - `Phone` service: + Angular 2 services available to Angular 1 code. Use it to plug in the `Phone` service: + + `UpgradeAdapter`有一个`downgradeNg2Provider`方法,用于让Angular 2的服务对Angular 1的代码可用。用它来插入`Phone`服务: - `UpgradeAdapter`有个`downgradeNg2Provider`方法就是用来让Angular 2的服务在Angular 1的代码中可用的。 - 我们可以使用它来插入我们的`Phone`服务: - -+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'phone-service', 'app/main.ts') ++makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'phone-service', 'app/main.ts (excerpt)')(format='.') :marked - Note that we actually needed to do two registrations here: - - 注意,我们实际上做了两次注册: - - 1. Register `Phone` as an **Angular 2 provider** with the `addProvider` - method. That's the same method that we used earlier for `HTTP_PROVIDERS`. - - 1. 用`addProvider`方法注册了一个名叫`Phone`的**Angular 2提供商**。这和我们以前使用`HTTP_PROVIDERS`的方法一样。 - - 2. Register an **Angular 1 factory** called `phone`, which will be a *downgraded* - version of the `Phone` Angular 2 service. - - 2. 注册了一个名叫`phone`的**Angular 1工厂**,它是一个`Phones`服务的*降级*版。 - Now that we are loading `phone.service.ts` through an import that is resolved by SystemJS, we should **remove the <script> tag** for the service from `index.html`. This is something we'll do to all our components as we upgrade them. Simultaneously @@ -1868,100 +1897,111 @@ code-example(format=""). 但是在Angular 2中,我们要有一个专门指定的选择器。本组件将会对应元素名字`phone-list`,和Angular 1版本一样。 We now also need to convert the template of this component into Angular 2 syntax. - In the search controls we need to use Angular 2 syntax for the two `ngModel`s. - We should also no longer use the `$ctrl` prefix in expressions: + The search controls replace the Angular 1 `$ctrl` expressions + with Angular 2's two-way `[(ngModel)]` binding syntax: - 现在,我们同时需要将组件的模版也转换为Angular 2语法。在搜索控制中,我们需要为两个`ngModel`使用Angular 2语法。 - 我们应该不需要再在表达式中使用`$ctrl`前缀: + 现在,我们还需要将组件的模版也转换为Angular 2语法。在搜索控件中,我们要为把Angular 1的`$ctrl`表达式替换成Angular 2的双向绑定语法`[(ngModel)]`: -+makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.template.html', 'controls', 'app/phone-list/phone-list.template.html') ++makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.template.html', 'controls', 'app/phone-list/phone-list.template.html (search controls)')(format='.') :marked - In the list we need to replace the `ng-repeat` with an `*ngFor` and the - `let var of iterable` syntax, which is [described in our - Template Syntax guide](../guide/template-syntax.html#directives). - For the images, we can replace `ng-src` with a binding to the standard `src` property. + Replace the list's `ng-repeat` with an `*ngFor` as + [described in the Template Syntax page](../guide/template-syntax.html#directives). + Replace the image tag's `ng-src` with a binding to the native `src` property. - 在列表中,我们需要把`ng-repeat`替换为`*ngFor`以及它的`let var of iterable`语法, + 我们需要把列表中的`ng-repeat`替换为`*ngFor`以及它的`let var of iterable`语法, 该语法在[模板语法指南中讲过](../guide/template-syntax.html#directives)。 - 对于图片,我们可以把`ng-src`替换为一个标准的`src`属性(property)绑定。 + 对于图片,我们可以把`img`标签的`ng-src`替换为一个标准的`src`属性(property)绑定。 -+makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.template.html', 'list', 'app/phone-list/phone-list.template.html') ++makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.template.html', 'list', 'app/phone-list/phone-list.template.html (phones)')(format='.') :marked - Another thing that we've done here is that we've removed the use of `filter` and `orderBy` filters, - and replaced them with a call to the `getPhones()` controller method. - The built-in Angular filters `filter` and `orderBy` do not exist in Angular 2, - so we need to do the filtering and sorting ourselves. We could define our own Angular 2 - pipes for this purpose, but in this case it is more convenient to just implement the filtering - and ordering logic in the component itself. We expect the `getPhones()` method to return a collection - where the current filtering and ordering has been applied. + ### No Angular 2 _filter_ or _orderBy_ filters + ### Angular 2中没有`filter`或`orderBy`过滤器 + + The built-in Angular 1 `filter` and `orderBy` filters do not exist in Angular 2, + so we need to do the filtering and sorting ourselves. + + Angular 2中并不存在Angular 1中内置的`filter`和`orderBy`过滤器。 + 所以我们得自己实现进行过滤和排序。 + + We replaced the `filter` and `orderBy` filters with bindings to the `getPhones()` controller method, + which implements the filtering and ordering logic inside the component itself. - 我们在这里做的另一件事就是移除了`filter`和`orderBy`过滤器的使用,并把它们换成对控制器中`getPhones()`方法的调用。 - 内置的`filter`和`orderBy`在Angular 2中已经不存在了,所以我们得自己进行过滤和排序。 - 我们可以为此定义自己的Angular 2管道,但是在这个案例中,在组件本身实现过滤和排序逻辑反倒更方便。 - 我们希望`getPhones()`方法直接返回一个应用过当前过滤和排序规则的集合。 + 我们把`filter`和`orderBy`过滤器改成绑定到控制器中的`getPhones()`方法,通过该方法,组件本身实现了过滤和排序逻辑。 +makeExample('upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ts', 'getphones', 'app/phone-list/phone-list.component.ts') :marked - In the entrypoint file `main.ts` we're going to plug this component into our application. Instead - of registering a component, we register a `phoneList` *directive*. - The directive is a downgraded version of our Angular 2 component, and the `UpgradeAdapter` - handles the bridging between the two: + The new `PhoneListComponent` uses the Angular 2 `ngModel` directive, located in the `FormsModule`. + Add the `FormsModule` to `NgModule` imports and declare the new `PhoneListComponent` : - 在模块文件中,我们将把这个组件插入到程序中。我们不再注册控制器,而是注册一个`pcPhoneList`指令。 - 该指令是我们那个组件的降级版本,`UpgradeAdapter`负责桥接它们: + 新的`PhoneListComponent`使用Angular 2的`ngModel`指令,它位于`FormsModule`中。 + 把`FormsModule`添加到`NgModule`的`imports`中,并声明新的`PhoneListComponent`组件: -+makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'phone-list', 'app/main.ts') ++makeExample('upgrade-phonecat-2-hybrid/ts/app/app.module.ts', 'phonelist', 'app.module.ts') :marked - The `` type annotation here is to let the TypeScript compiler - know that the return value of the downgrade method call will be something that can be - used as a directive factory. + In the entrypoint file `main.ts` we'll plug this component into the Angular 1 module. + + 在入口点文件`main.ts`中,我们把该组件插入到Angular 1的模块中。 + + Instead of registering a component, we register a `phoneList` *directive*, a downgraded version of the Angular 2 component. + The `UpgradeAdapter` creates the bridge between the two: - 这里的``类型注解是为了让TypeScript编译器知道这个 - 降级方法(`downgradeNg2Component`)的返回值能作为指令工厂使用。 + 我们注册了一个`phoneList`*指令*而不是组件,指令是Angular 2组件的降级版。`UpgradeAdapter`在两者之间架起了桥梁: - At this point, also remove the <script> tag for the phone list component from `index.html`. ++makeExample('upgrade-phonecat-2-hybrid/ts/app/main.ts', 'phone-list', 'app/main.ts (excerpt)')(format='.') - 这时,也从`index.html`中移除电话列表组件的`