diff --git a/gulpfile.js b/gulpfile.js index 448f9afb48..73778bb19e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -86,21 +86,46 @@ var _exampleBoilerplateFiles = [ var _exampleDartWebBoilerPlateFiles = ['styles.css']; -// --filter may be passed in to filter/select _example app subdir names -// i.e. gulp run-e2e-tests --filter=foo ; would select all example apps with -// 'foo' in their folder names. +/** + * Run Protractor End-to-End Tests for Doc Samples + * + * Flags + * --filter to filter/select _example app subdir names + * e.g. gulp run-e2e-tests --filter=foo // all example apps with 'foo' in their folder names. + * + * --fast by-passes the npm install and webdriver update + * Use it for repeated test runs (but not the FIRST run) + * e.g. gulp run-e2e-tests --fast + * + * --lang to filter by code language + * e.g. gulp run-e2e-tests --lang=ts // only TypeScript apps + * default is (ts|js) + * all means (ts|js|dart) + */ gulp.task('run-e2e-tests', function() { - var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH}); - return spawnInfo.promise.then(function() { - copyExampleBoilerplate(); - var exePath = path.join(process.cwd(), "./node_modules/.bin/"); - spawnInfo = spawnExt('webdriver-manager', ['update'], {cwd: exePath}); - return spawnInfo.promise; - }).then(function() { + + var exePath = path.join(process.cwd(), "./node_modules/.bin/"); + + var promise; + if (argv.fast) { + // fast; skip all setup + promise = Promise.resolve(true); + } else { + // Not 'fast'; do full setup + var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH}); + promise = spawnInfo.promise.then(function() { + copyExampleBoilerplate(); + spawnInfo = spawnExt('webdriver-manager', ['update'], {cwd: exePath}); + return spawnInfo.promise; + }); + } + + promise.then(function() { return findAndRunE2eTests(argv.filter); }).then(function(status) { reportStatus(status); - }).fail(function(e) { + }).catch(function(e) { + gutil.log(e); return e; }); }); @@ -114,10 +139,13 @@ function findAndRunE2eTests(filter) { var startTime = new Date().getTime(); // create an output file with header. var outputFile = path.join(process.cwd(), 'protractor-results.txt'); - var header = "Protractor example results for " + lang + " on " + (new Date()).toLocaleString() + "\n\n"; - if (filter) { - header += ' Filter: ' + filter.toString() + '\n\n'; - } + + var header = `Doc Sample Protractor Results for ${lang} on ${new Date().toLocaleString()}\n`; + header += argv.fast ? + ' Fast Mode (--fast): no npm install, webdriver update, or boilerplate copy\n' : + ' Slow Mode: npm install, webdriver update, and boilerplate copy\n'; + header += ` Filter: ${filter ? filter : 'All tests'}\n\n`; + fs.writeFileSync(outputFile, header); // create an array of combos where each @@ -175,25 +203,32 @@ function runE2eTsTests(appDir, protractorConfigFilename, outputFile) { } function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile) { - return prepPromise.then(function (data) { - // start protractor - var pcFilename = path.resolve(protractorConfigFilename); // need to resolve because we are going to be running from a different dir - var exePath = path.join(process.cwd(), "./node_modules/.bin/"); - var spawnInfo = spawnExt('protractor', - [ pcFilename, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: exePath }); - return spawnInfo.promise; - }).then(function(data) { - // kill the app now that protractor has completed. - // Ugh... proc.kill does not work properly on windows with child processes. - // appRun.proc.kill(); - treeKill(appRunSpawnInfo.proc.pid); - return !data; - }).fail(function(err) { - // Ugh... proc.kill does not work properly on windows with child processes. - // appRun.proc.kill(); - treeKill(appRunSpawnInfo.proc.pid); - return false; - }); + return prepPromise + .catch(function(){ + var emsg = `AppDir failed during compile: ${appDir}\n\n`; + gutil.log(emsg); + fs.appendFileSync(outputFile, emsg); + return Promise.reject(emsg); + }) + .then(function (data) { + // start protractor + var pcFilename = path.resolve(protractorConfigFilename); // need to resolve because we are going to be running from a different dir + var exePath = path.join(process.cwd(), "./node_modules/.bin/"); + var spawnInfo = spawnExt('protractor', + [ pcFilename, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: exePath }); + return spawnInfo.promise + }) + .then( + function() { return finish(true);}, + function() { return finish(false);} + ) + + function finish(ok){ + // Ugh... proc.kill does not work properly on windows with child processes. + // appRun.proc.kill(); + treeKill(appRunSpawnInfo.proc.pid); + return ok; + } } // start the server in appDir/build/web; then run protractor with the specified @@ -252,9 +287,11 @@ function spawnExt(command, args, options) { proc.stderr.on('data', function (data) { gutil.log(data.toString()); }); - proc.on('close', function (data) { + proc.on('close', function (returnCode) { gutil.log('completed: ' + descr); - deferred.resolve(data); + // Many tasks (e.g., tsc) complete but are actually errors; + // Confirm return code is zero. + returnCode === 0 ? deferred.resolve(0) : deferred.reject(returnCode); }); proc.on('error', function (data) { gutil.log('completed with error:' + descr); diff --git a/public/docs/_examples/cb-component-communication/ts/app/countdown-timer.component.ts b/public/docs/_examples/cb-component-communication/ts/app/countdown-timer.component.ts index 83f5751d5b..262ed6f832 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/countdown-timer.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/app/countdown-timer.component.ts @@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; @Component({ - selector:'countdown-timer', + selector: 'countdown-timer', template: '

{{message}}

' }) export class CountdownTimerComponent implements OnInit, OnDestroy { @@ -24,12 +24,12 @@ export class CountdownTimerComponent implements OnInit, OnDestroy { private countDown() { this.clearTimer(); - this.intervalId = setInterval(()=>{ + this.intervalId = window.setInterval(() => { this.seconds -= 1; - if (this.seconds == 0) { - this.message = "Blast off!"; + if (this.seconds === 0) { + this.message = 'Blast off!'; } else { - if (this.seconds < 0) { this.seconds = 10;} // reset + if (this.seconds < 0) { this.seconds = 10; } // reset this.message = `T-${this.seconds} seconds and counting`; } }, 1000); diff --git a/public/docs/_examples/cb-component-relative-paths/e2e-spec.js b/public/docs/_examples/cb-component-relative-paths/e2e-spec.js new file mode 100644 index 0000000000..6646bd0b4f --- /dev/null +++ b/public/docs/_examples/cb-component-relative-paths/e2e-spec.js @@ -0,0 +1,32 @@ +describe('Cookbook: component-relative paths', function () { + + function getPageStruct() { + return { + title: element( by.tagName( 'h1' )), + absComp: element( by.css( 'absolute-path div' ) ), + relComp: element( by.css( 'relative-path div' ) ) + } + } + + var page; + beforeAll(function () { + browser.get(''); + page = getPageStruct(); + }); + + it('should display title of the sample', function () { + expect(element(by.tagName('h1')).getText()).toContain('Paths'); + }); + + it('should have absolute-path element', function () { + expect(page.absComp.isPresent()).toBe(true, 'no element'); + }); + + it('should display the absolute path text', function () { + expect(page.absComp.getText()).toContain('Absolute'); + }); + + it('should display the component-relative path text', function () { + expect(page.relComp.getText()).toContain('Component-relative'); + }); +}); diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts new file mode 100644 index 0000000000..09ccc94591 --- /dev/null +++ b/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts @@ -0,0 +1,15 @@ +// #docregion +import { Component } from '@angular/core'; + +import { SomeAbsoluteComponent, SomeRelativeComponent} from './some.component'; + +@Component({ +selector: 'my-app', +template: + `

Absolute & Component-Relative Paths

+ + + `, + directives: [SomeAbsoluteComponent, SomeRelativeComponent] +}) +export class AppComponent {} diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/main.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/main.ts new file mode 100644 index 0000000000..42dbeb9f7d --- /dev/null +++ b/public/docs/_examples/cb-component-relative-paths/ts/app/main.ts @@ -0,0 +1,5 @@ +import { bootstrap } from '@angular/platform-browser-dynamic'; + +import { AppComponent } from './app.component'; + +bootstrap(AppComponent); diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.css b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.css new file mode 100644 index 0000000000..f43e11f60e --- /dev/null +++ b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.css @@ -0,0 +1,22 @@ +/* #docregion */ +div.absolute { + background: beige; + border: 1px solid darkred; + color: red; + margin: 8px; + max-width: 20em; + padding: 4px; + text-align: center; +} + +div.relative { + background: powderblue; + border: 1px solid darkblue; + color: Blue; + font-style: italic; + margin: 8px; + max-width: 20em; + padding: 4px; + text-align: center; +} + diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.html b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.html new file mode 100644 index 0000000000..027741ce55 --- /dev/null +++ b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.html @@ -0,0 +1,4 @@ + +
+ {{type}}
{{path}} +
diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts new file mode 100644 index 0000000000..2bd56c6930 --- /dev/null +++ b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts @@ -0,0 +1,37 @@ +// #docregion +import { Component } from '@angular/core'; + +///////// Using Absolute Paths /////// + +// #docregion absolute-config +@Component({ + selector: 'absolute-path', + templateUrl: 'app/some.component.html', + styleUrls: ['app/some.component.css'] +}) +// #enddocregion absolute-config +export class SomeAbsoluteComponent { + class = 'absolute'; + type = 'Absolute template & style URLs'; + path = 'app/path.component.html'; +} + +///////// Using Relative Paths /////// + +// #docregion relative-config +@Component({ + // #docregion module-id + moduleId: module.id, + // #enddocregion module-id + selector: 'relative-path', + templateUrl: 'some.component.html', + styleUrls: ['some.component.css'] +}) +// #enddocregion relative-config + +export class SomeRelativeComponent { + class = 'relative'; + type = 'Component-relative template & style URLs'; + path = 'path.component.html'; + +} diff --git a/public/docs/_examples/cb-component-relative-paths/ts/example-config.json b/public/docs/_examples/cb-component-relative-paths/ts/example-config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/cb-component-relative-paths/ts/index.html b/public/docs/_examples/cb-component-relative-paths/ts/index.html new file mode 100644 index 0000000000..cc0d972df2 --- /dev/null +++ b/public/docs/_examples/cb-component-relative-paths/ts/index.html @@ -0,0 +1,31 @@ + + + + + + + + + Component-Relative Paths + + + + + + + + + + + + + + + + + + Loading app... + + diff --git a/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json b/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json new file mode 100644 index 0000000000..a4c33bbde3 --- /dev/null +++ b/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json @@ -0,0 +1,8 @@ +{ + "description": "Module-relative Paths", + "files": [ + "!**/*.d.ts", + "!**/*.js" + ], + "tags": [ "cookbook" ] +} diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/main.ts b/public/docs/_examples/cb-dependency-injection/ts/app/main.ts index 508177e81b..595971625e 100644 --- a/public/docs/_examples/cb-dependency-injection/ts/app/main.ts +++ b/public/docs/_examples/cb-dependency-injection/ts/app/main.ts @@ -8,7 +8,7 @@ import { LocationStrategy, import { HeroData } from './hero-data'; import { InMemoryBackendService, - SEED_DATA } from 'angular2-in-memory-web-api/core'; + SEED_DATA } from 'angular2-in-memory-web-api'; import { AppComponent } from './app.component'; diff --git a/public/docs/_examples/karma-test-shim.js b/public/docs/_examples/karma-test-shim.js index e2aff07852..bc8cf372f3 100644 --- a/public/docs/_examples/karma-test-shim.js +++ b/public/docs/_examples/karma-test-shim.js @@ -1,90 +1,93 @@ -/*global jasmine, __karma__, window*/ -(function () { - -// Error.stackTraceLimit = Infinity; - +// /*global jasmine, __karma__, window*/ +Error.stackTraceLimit = Infinity; jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; -// Cancel Karma's synchronous start, -// we call `__karma__.start()` later, once all the specs are loaded. -__karma__.loaded = function () { }; +__karma__.loaded = function () { +}; -// SET THE RUNTIME APPLICATION ROOT HERE -var appRoot ='app'; // no trailing slash! - -// RegExp for client application base path within karma (which always starts 'base\') -var karmaBase = '^\/base\/'; // RegEx string for base of karma folders -var appPackage = 'base/' + appRoot; //e.g., base/app -var appRootRe = new RegExp(karmaBase + appRoot + '\/'); -var onlyAppFilesRe = new RegExp(karmaBase + appRoot + '\/(?!.*\.spec\.js$)([a-z0-9-_\.\/]+)\.js$'); - -var moduleNames = []; - -// Configure systemjs packages to use the .js extension for imports from the app folder -var packages = {}; -packages[appPackage] = { - defaultExtension: false, - format: 'register', - map: Object.keys(window.__karma__.files) - .filter(onlyAppFiles) - // Create local module name mapping to karma file path for app files - // with karma's fingerprint in query string, e.g.: - // './hero.service': '/base/app/hero.service.js?f4523daf879cfb7310ef6242682ccf10b2041b3e' - .reduce(function (pathsMapping, appPath) { - var moduleName = appPath.replace(appRootRe, './').replace(/\.js$/, ''); - pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath]; - return pathsMapping; - }, {}) - } - -System.config({ packages: packages }); - -// Configure Angular for the browser and -// with test versions of the platform providers - Promise.all([ - System.import('angular2/testing'), - System.import('angular2/platform/testing/browser') - ]) - .then(function (results) { - var testing = results[0]; - var browser = results[1]; - testing.setBaseTestProviders( - browser.TEST_BROWSER_PLATFORM_PROVIDERS, - browser.TEST_BROWSER_APPLICATION_PROVIDERS); - - // Load all spec files - // (e.g. 'base/app/hero.service.spec.js') - return Promise.all( - Object.keys(window.__karma__.files) - .filter(onlySpecFiles) - .map(function (moduleName) { - moduleNames.push(moduleName); - return System.import(moduleName); - })); - }) - - .then(success, fail); - -////// Helpers ////// - -function onlyAppFiles(filePath) { - return onlyAppFilesRe.test(filePath); +function isJsFile(path) { + return path.slice(-3) == '.js'; } -function onlySpecFiles(filePath) { - return /\.spec\.js$/.test(filePath); +function isSpecFile(path) { + return /\.spec\.js$/.test(path); } -function success () { - console.log( - 'Spec files loaded:\n ' + - moduleNames.join('\n ') + - '\nStarting Jasmine testrunner'); - __karma__.start(); +function isBuiltFile(path) { + var builtPath = '/base/app/'; + return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath); } -function fail(error) { - __karma__.error(error.stack || error); +var allSpecFiles = Object.keys(window.__karma__.files) + .filter(isSpecFile) + .filter(isBuiltFile); + +////////////////////////// +// Load our SystemJS configuration. + +// map tells the System loader where to look for things +var map = { + 'app': 'app', + + '@angular': 'node_modules/@angular', + 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', + 'rxjs': 'node_modules/rxjs' +}; + +// packages tells the System loader how to load when no filename and/or no extension +var packages = { + 'app': { main: 'main.js', defaultExtension: 'js' }, + 'rxjs': { defaultExtension: 'js' }, + 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, +}; + +var ngPackageNames = [ + 'common', + 'compiler', + 'core', + 'http', + 'platform-browser', + 'platform-browser-dynamic', + 'router', + 'router-deprecated', + 'upgrade', +]; + +// Add package entries for angular packages +ngPackageNames.forEach(function(pkgName) { + + // Bundled (~40 requests): DOESN'T WORK IN KARMA OR WALLABY (YET?) + //packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' }; + + // Individual files (~300 requests): + packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; +}); + +var config = { + baseURL: '/base', + map: map, + packages: packages } -})(); +System.config(config); +////////////// + +Promise.all([ + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') +]).then(function (providers) { + var testing = providers[0]; + var testingBrowser = providers[1]; + + testing.setBaseTestProviders( + testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, + testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); + +}).then(function() { + // Finally, load all spec files. + // This will run the tests directly. + return Promise.all( + allSpecFiles.map(function (moduleName) { + return System.import(moduleName); + })); +}).then(__karma__.start, __karma__.error); diff --git a/public/docs/_examples/karma.conf.js b/public/docs/_examples/karma.conf.js index b9bea32636..d39e2ffac8 100644 --- a/public/docs/_examples/karma.conf.js +++ b/public/docs/_examples/karma.conf.js @@ -21,34 +21,30 @@ module.exports = function(config) { } }, files: [ - // Polyfills. - 'node_modules/code-js/client/shim.min.js', + // System.js for module loading + 'node_modules/systemjs/dist/system.src.js', - // Zone.js dependencies - // Note - do not include zone.js itself here, it is already - // included in angular2-polyfills + // Polyfills + 'node_modules/core-js/client/shim.js', + + // Reflect and Zone.js + 'node_modules/reflect-metadata/Reflect.js', 'node_modules/zone.js/dist/zone.js', 'node_modules/zone.js/dist/jasmine-patch.js', 'node_modules/zone.js/dist/async-test.js', 'node_modules/zone.js/dist/fake-async-test.js', - { pattern: 'node_modules/reflect-metadata/Reflect.js', included: true, watched: false }, - { pattern: 'https://code.angularjs.org/tools/system.js', included: true, watched: false }, - // RxJs. { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, - {pattern: 'karma-test-shim.js', included: true, watched: true}, - {pattern: 'built/test/matchers.js', included: true, watched: true}, + // Angular 2 itself and the testing library + {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false}, + {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false}, - // paths loaded via module imports - {pattern: 'built/**/*.js', included: false, watched: true}, + 'karma-test-shim.js', - {pattern: 'node_modules/@angular/**/*.js', included: false, watched: true}, - {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: true}, - - // transpiled application & spec code paths to be loaded via module imports + // transpiled application & spec code paths loaded via module imports {pattern: appBase + '**/*.js', included: false, watched: true}, // asset (HTML & CSS) paths loaded via Angular's component compiler diff --git a/public/docs/_examples/server-communication/dart/.docsync.json b/public/docs/_examples/server-communication/dart/.docsync.json new file mode 100644 index 0000000000..09097599c8 --- /dev/null +++ b/public/docs/_examples/server-communication/dart/.docsync.json @@ -0,0 +1,4 @@ +{ + "name": "HTTP client (server communication)" + "docHref": "https://angular.io/docs/dart/latest/guide/server-communication.html" +} diff --git a/public/docs/_examples/server-communication/dart/lib/app_component.dart b/public/docs/_examples/server-communication/dart/lib/app_component.dart index 55c91e6e4d..cd52ca413f 100644 --- a/public/docs/_examples/server-communication/dart/lib/app_component.dart +++ b/public/docs/_examples/server-communication/dart/lib/app_component.dart @@ -1,13 +1,13 @@ // #docplaster // #docregion -import "package:angular2/core.dart" show Component; +import 'package:angular2/core.dart'; -import "toh/hero_list_component.dart" show HeroListComponent; -import "wiki/wiki_component.dart" show WikiComponent; -import "wiki/wiki_smart_component.dart" show WikiSmartComponent; +import 'toh/hero_list_component.dart'; +import 'wiki/wiki_component.dart'; +import 'wiki/wiki_smart_component.dart'; @Component( - selector: "my-app", + selector: 'my-app', template: ''' diff --git a/public/docs/_examples/server-communication/dart/lib/toh/hero.dart b/public/docs/_examples/server-communication/dart/lib/toh/hero.dart index 6e788437c7..a990373a72 100644 --- a/public/docs/_examples/server-communication/dart/lib/toh/hero.dart +++ b/public/docs/_examples/server-communication/dart/lib/toh/hero.dart @@ -1,4 +1,6 @@ // #docregion +int _toInt(id) => id is int ? id : int.parse(id); + class Hero { final int id; final String name; @@ -9,6 +11,4 @@ class Hero { new Hero(_toInt(hero['id']), hero['name']); Map toJson() => {'id': id, 'name': name}; - - static int _toInt(id) => id is int ? id : int.parse(id); } diff --git a/public/docs/_examples/server-communication/dart/lib/toh/hero_service.dart b/public/docs/_examples/server-communication/dart/lib/toh/hero_service.dart index d8d602d2e7..5da269fff7 100644 --- a/public/docs/_examples/server-communication/dart/lib/toh/hero_service.dart +++ b/public/docs/_examples/server-communication/dart/lib/toh/hero_service.dart @@ -6,12 +6,12 @@ import 'dart:convert'; import 'hero.dart'; import 'package:angular2/core.dart'; import 'package:http/browser_client.dart'; -import 'package:http/http.dart' show Response; +import 'package:http/http.dart'; @Injectable() class HeroService { // #docregion endpoint, http-get - final String _heroesUrl = 'app/heroes'; // URL to web API + static const _heroesUrl = 'app/heroes'; // URL to web API // #enddocregion endpoint, http-get final BrowserClient _http; @@ -35,7 +35,7 @@ class HeroService { // #docregion addhero, addhero-sig Future addHero(String name) async { - // #enddocregion addhero-sig + // #enddocregion addhero-sig try { final response = await _http.post(_heroesUrl, headers: {'Content-Type': 'application/json'}, @@ -50,8 +50,8 @@ class HeroService { // #docregion extract-data dynamic _extractData(Response res) { var body = JSON.decode(res.body); - // TODO: once fixed, https://github.com/adaojunior/http-in-memory-web-api/issues/1 - // Drop the `?? body` term + // TODO: https://github.com/adaojunior/http-in-memory-web-api/issues/1 + // Once #1 is fixed, drop the `?? body` term: return body['data'] ?? body; } // #enddocregion extract-data @@ -69,6 +69,6 @@ class HeroService { /* // #docregion endpoint-json - private _heroesUrl = 'heroes.json'; // URL to JSON file + static const _heroesUrl = 'heroes.json'; // URL to JSON file // #enddocregion endpoint-json */ diff --git a/public/docs/_examples/server-communication/dart/pubspec.yaml b/public/docs/_examples/server-communication/dart/pubspec.yaml index 60e431bf51..6b1e961d75 100644 --- a/public/docs/_examples/server-communication/dart/pubspec.yaml +++ b/public/docs/_examples/server-communication/dart/pubspec.yaml @@ -23,4 +23,3 @@ transformers: resolved_identifiers: BrowserClient: 'package:http/browser_client.dart' - dart_to_js_script_rewriter -# #enddocregion transformers diff --git a/public/docs/_examples/server-communication/dart/web/main.dart b/public/docs/_examples/server-communication/dart/web/main.dart index a66ddb454b..ca055c9d10 100644 --- a/public/docs/_examples/server-communication/dart/web/main.dart +++ b/public/docs/_examples/server-communication/dart/web/main.dart @@ -1,10 +1,10 @@ // #docplaster // #docregion final -import 'package:angular2/core.dart' show Provider; +import 'package:angular2/core.dart'; // #docregion v1 -import 'package:angular2/platform/browser.dart' show bootstrap; +import 'package:angular2/platform/browser.dart'; // #docregion http-providers -import 'package:http/browser_client.dart' show BrowserClient; +import 'package:http/browser_client.dart'; // #enddocregion http-providers import 'package:server_communication/app_component.dart'; diff --git a/public/docs/_examples/server-communication/ts/app/main.ts b/public/docs/_examples/server-communication/ts/app/main.ts index 870548bd32..ceae9a4825 100644 --- a/public/docs/_examples/server-communication/ts/app/main.ts +++ b/public/docs/_examples/server-communication/ts/app/main.ts @@ -5,7 +5,7 @@ import { provide } from '@angular/core'; import { XHRBackend } from '@angular/http'; import { InMemoryBackendService, - SEED_DATA } from 'angular2-in-memory-web-api/core'; + SEED_DATA } from 'angular2-in-memory-web-api'; import { HeroData } from './hero-data'; // The usual bootstrapping imports diff --git a/public/docs/_examples/systemjs.config.js b/public/docs/_examples/systemjs.config.js index dc5c1484b6..56d5f61e5f 100644 --- a/public/docs/_examples/systemjs.config.js +++ b/public/docs/_examples/systemjs.config.js @@ -17,7 +17,7 @@ var packages = { 'app': { main: 'main.js', defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' }, - 'angular2-in-memory-web-api': { defaultExtension: 'js' }, + 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, }; var ngPackageNames = [ diff --git a/public/docs/_examples/systemjs.config.plunker.js b/public/docs/_examples/systemjs.config.plunker.js index 29a93a07c4..9e13e14edb 100644 --- a/public/docs/_examples/systemjs.config.plunker.js +++ b/public/docs/_examples/systemjs.config.plunker.js @@ -22,7 +22,7 @@ var packages = { 'app': { main: 'main.ts', defaultExtension: 'ts' }, 'rxjs': { defaultExtension: 'js' }, - 'angular2-in-memory-web-api': { defaultExtension: 'js' }, + 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, }; var ngPackageNames = [ diff --git a/public/docs/_examples/testing/ts/app/app.component.spec.ts b/public/docs/_examples/testing/ts/app/app.component.spec.ts index 1cabad6050..2b53c38dcc 100644 --- a/public/docs/_examples/testing/ts/app/app.component.spec.ts +++ b/public/docs/_examples/testing/ts/app/app.component.spec.ts @@ -8,8 +8,10 @@ import { beforeEach, beforeEachProviders, describe, ddescribe, xdescribe, expect, it, iit, xit, - async, inject, ComponentFixture, TestComponentBuilder -} from '@angular/testing'; + async, inject +} from '@angular/core/testing'; + +import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; import { Hero, HeroService, MockHeroService } from './mock-hero.service'; @@ -18,7 +20,7 @@ import { Router, MockRouter, RouterOutlet, MockRouterOutlet} from './mock-router'; describe('AppComponent', () => { - let fixture: ComponentFixture; + let fixture: ComponentFixture; let comp: AppComponent; beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { diff --git a/public/docs/_examples/testing/ts/app/app.component.ts b/public/docs/_examples/testing/ts/app/app.component.ts index 8b1d897411..bf10177937 100644 --- a/public/docs/_examples/testing/ts/app/app.component.ts +++ b/public/docs/_examples/testing/ts/app/app.component.ts @@ -3,10 +3,10 @@ import { Component } from '@angular/core'; // Can't test with ROUTER_DIRECTIVES yet -// import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router'; +// import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; import { RouteConfig, RouterLink, - RouterOutlet, ROUTER_PROVIDERS } from '@angular/router'; + RouterOutlet, ROUTER_PROVIDERS } from '@angular/router-deprecated'; import { DashboardComponent } from './dashboard.component'; import { HeroesComponent } from './heroes.component'; diff --git a/public/docs/_examples/testing/ts/app/bad-tests.spec.ts b/public/docs/_examples/testing/ts/app/bad-tests.spec.ts index a2158f873d..eaeab08128 100644 --- a/public/docs/_examples/testing/ts/app/bad-tests.spec.ts +++ b/public/docs/_examples/testing/ts/app/bad-tests.spec.ts @@ -19,12 +19,13 @@ import { DebugElement } from '@angular/core'; import { By } from '@angular/platform-browser'; import { - beforeEach, beforeEachProviders, withProviders, + beforeEach, beforeEachProviders, describe, ddescribe, xdescribe, expect, it, iit, xit, - async, inject, fakeAsync, tick, - ComponentFixture, TestComponentBuilder -} from '@angular/testing'; + async, inject +} from '@angular/core/testing'; + +import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; import { provide } from '@angular/core'; import { ViewMetadata } from '@angular/core'; @@ -90,7 +91,7 @@ xdescribe('async & inject testing errors', () => { let itPromise = patchJasmineIt(); it('should fail with an error from a promise', async(() => { - return Promise.reject('baz') + return Promise.reject('baz'); })); itPromise.then( diff --git a/public/docs/_examples/testing/ts/app/bag.spec.ts b/public/docs/_examples/testing/ts/app/bag.spec.ts index 0d27516eb8..c6eae1bc77 100644 --- a/public/docs/_examples/testing/ts/app/bag.spec.ts +++ b/public/docs/_examples/testing/ts/app/bag.spec.ts @@ -16,12 +16,14 @@ import { DebugElement } from '@angular/core'; import { By } from '@angular/platform-browser'; import { - beforeEach, beforeEachProviders, withProviders, + beforeEach, beforeEachProviders, describe, ddescribe, xdescribe, expect, it, iit, xit, - async, inject, fakeAsync, tick, - ComponentFixture, TestComponentBuilder -} from '@angular/testing'; + async, inject, + fakeAsync, tick, withProviders +} from '@angular/core/testing'; + +import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; import { provide } from '@angular/core'; import { ViewMetadata } from '@angular/core'; @@ -349,7 +351,7 @@ describe('test component builder', function() { })), 10000); // Long timeout because this test makes an actual XHR. describe('(lifecycle hooks w/ MyIfParentComp)', () => { - let fixture: ComponentFixture; + let fixture: ComponentFixture; let parent: MyIfParentComp; let child: MyIfChildComp; diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts b/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts index af7108cc92..5dd61bc8f3 100644 --- a/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts +++ b/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts @@ -8,8 +8,10 @@ import { beforeEach, beforeEachProviders, describe, ddescribe, xdescribe, expect, it, iit, xit, - async, inject, TestComponentBuilder -} from '@angular/testing'; + async, inject +} from '@angular/core/testing'; + +import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; import { Hero, HeroService, MockHeroService } from './mock-hero.service'; import { Router, MockRouter } from './mock-router'; diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.ts b/public/docs/_examples/testing/ts/app/dashboard.component.ts index 73edbd98ad..69a9c5cce6 100644 --- a/public/docs/_examples/testing/ts/app/dashboard.component.ts +++ b/public/docs/_examples/testing/ts/app/dashboard.component.ts @@ -2,7 +2,7 @@ // #docregion import { Component, OnInit } from '@angular/core'; // #docregion import-router -import { Router } from '@angular/router'; +import { Router } from '@angular/router-deprecated'; // #enddocregion import-router import { Hero } from './hero'; diff --git a/public/docs/_examples/testing/ts/app/hero-detail.component.ts b/public/docs/_examples/testing/ts/app/hero-detail.component.ts index 98c0271bf5..3e1eaf4cd8 100644 --- a/public/docs/_examples/testing/ts/app/hero-detail.component.ts +++ b/public/docs/_examples/testing/ts/app/hero-detail.component.ts @@ -5,7 +5,7 @@ import { Component, OnInit } from '@angular/core'; // #enddocregion import-oninit // #docregion import-route-params -import {RouteParams} from '@angular/router'; +import {RouteParams} from '@angular/router-deprecated'; // #enddocregion import-route-params import { Hero } from './hero'; diff --git a/public/docs/_examples/testing/ts/app/heroes.component.ts b/public/docs/_examples/testing/ts/app/heroes.component.ts index d539c1c21e..1e2651f256 100644 --- a/public/docs/_examples/testing/ts/app/heroes.component.ts +++ b/public/docs/_examples/testing/ts/app/heroes.component.ts @@ -1,7 +1,7 @@ // #docplaster // #docregion import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router } from '@angular/router-deprecated'; import { Hero } from './hero'; import { HeroDetailComponent } from './hero-detail.component'; @@ -47,4 +47,4 @@ export class HeroesComponent implements OnInit { } // #enddocregion heroes-component-renaming // #enddocregion class -// #enddocregion \ No newline at end of file +// #enddocregion diff --git a/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts b/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts index 1ddbb4190d..c80758e680 100644 --- a/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts +++ b/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts @@ -1,10 +1,12 @@ /* tslint:disable:no-unused-variable */ import { - beforeEach, beforeEachProviders, withProviders, + beforeEach, beforeEachProviders, describe, ddescribe, xdescribe, expect, it, iit, xit, - async, inject, TestComponentBuilder -} from '@angular/testing'; + async, inject, withProviders +} from '@angular/core/testing'; + +import { TestComponentBuilder } from '@angular/compiler/testing'; import { provide } from '@angular/core'; diff --git a/public/docs/_examples/testing/ts/app/mock-router.ts b/public/docs/_examples/testing/ts/app/mock-router.ts index d10eac06c0..547629f53d 100644 --- a/public/docs/_examples/testing/ts/app/mock-router.ts +++ b/public/docs/_examples/testing/ts/app/mock-router.ts @@ -1,10 +1,10 @@ -export * from '@angular/router'; +export * from '@angular/router-deprecated'; import { Directive, DynamicComponentLoader, ViewContainerRef, Injectable, Optional, Input } from '@angular/core'; import { ComponentInstruction, Instruction, - Router, RouterOutlet} from '@angular/router'; + Router, RouterOutlet} from '@angular/router-deprecated'; let _resolveToTrue = Promise.resolve(true); diff --git a/public/docs/_examples/toh-6/ts/app/main.ts b/public/docs/_examples/toh-6/ts/app/main.ts index 08caa81826..be838f0855 100644 --- a/public/docs/_examples/toh-6/ts/app/main.ts +++ b/public/docs/_examples/toh-6/ts/app/main.ts @@ -4,7 +4,7 @@ import { provide } from '@angular/core'; import { XHRBackend } from '@angular/http'; -import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api/core'; +import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api'; import { InMemoryDataService } from './in-memory-data.service'; // The usual bootstrapping imports diff --git a/public/docs/_examples/wallaby.js b/public/docs/_examples/wallaby.js index 7da9b779dd..2648c2c3aa 100644 --- a/public/docs/_examples/wallaby.js +++ b/public/docs/_examples/wallaby.js @@ -1,27 +1,25 @@ // Configuration for the Wallaby Visual Studio Code testing extension // https://marketplace.visualstudio.com/items?itemName=WallabyJs.wallaby-vscode // Note: Wallaby is not open source and costs money + module.exports = function () { return { files: [ // System.js for module loading - {pattern: 'node_modules/systemjs/dist/system-polyfills.js', instrument: false}, {pattern: 'node_modules/systemjs/dist/system.js', instrument: false}, // Polyfills - {pattern: 'node_modules/code-js/client/shim.min.js', instrument: false}, - {pattern: 'node_modules/angular2/bundles/angular2-polyfills.js', instrument: false}, + {pattern: 'node_modules/core-js/client/shim.min.js', instrument: false}, - // Zone.js dependencies - // Note - do not include zone.js itself or long-stack-trace-zone.js` here as - // they are included already in angular2-polyfills + // Reflect, Zone.js, and test shims + // Rx.js, Angular 2 itself, and the testing library not here because loaded by systemjs + {pattern: 'node_modules/reflect-metadata/Reflect.js', instrument: false}, + {pattern: 'node_modules/zone.js/dist/zone.js', instrument: false}, {pattern: 'node_modules/zone.js/dist/jasmine-patch.js', instrument: false}, {pattern: 'node_modules/zone.js/dist/async-test.js', instrument: false}, {pattern: 'node_modules/zone.js/dist/fake-async-test.js', instrument: false}, - // Rx.js, Angular 2 itself, and the testing library not here because loaded by systemjs - {pattern: 'app/**/*+(ts|html|css)', load: false}, {pattern: 'app/**/*.spec.ts', ignore: true} ], @@ -36,41 +34,24 @@ module.exports = function () { testFramework: 'jasmine', + debug: true, + bootstrap: function (wallaby) { wallaby.delayStart(); + systemConfig(); - System.config({ - defaultJSExtensions: true, - packages: { - app: { - meta: { - '*': { - scriptLoad: true - } - } - } - }, - paths: { - 'npm:*': 'node_modules/*' - }, - map: { - 'angular2': 'npm:angular2', - 'rxjs': 'npm:rxjs' - } - }); - - // Configure Angular for the browser and - // with test versions of the platform providers Promise.all([ - System.import('angular2/testing'), - System.import('angular2/platform/testing/browser') + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') ]) - .then(function (results) { - var testing = results[0]; - var browser = results[1]; + .then(function (providers) { + var testing = providers[0]; + var testingBrowser = providers[1]; + testing.setBaseTestProviders( - browser.TEST_BROWSER_PLATFORM_PROVIDERS, - browser.TEST_BROWSER_APPLICATION_PROVIDERS); + testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, + testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); + // Load all spec files return Promise.all(wallaby.tests.map(function (specFile) { @@ -85,8 +66,58 @@ module.exports = function () { throw e; }, 0); }); - }, - debug: true + ////////////////////////// + // SystemJS configuration. + function systemConfig() { + + // map tells the System loader where to look for things + var map = { + 'app': 'app', + + '@angular': 'node_modules/@angular', + 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', + 'rxjs': 'node_modules/rxjs' + }; + + // packages tells the System loader how to load when no filename and/or no extension + var packages = { + 'app': { main: 'main.js', defaultExtension: 'js' }, + 'rxjs': { defaultExtension: 'js' }, + 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, + }; + + var ngPackageNames = [ + 'common', + 'compiler', + 'core', + 'http', + 'platform-browser', + 'platform-browser-dynamic', + 'router', + 'router-deprecated', + 'upgrade', + ]; + + // Add package entries for angular packages + ngPackageNames.forEach(function(pkgName) { + + // Bundled (~40 requests): DOESN'T WORK IN WALLABY OR KARMA (YET?) + // packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' }; + + // Individual files (~300 requests): + packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; + }); + + var config = { + map: map, + packages: packages + } + + System.config(config); + } + ////////////////// + } }; + }; diff --git a/public/docs/dart/latest/_util-fns.jade b/public/docs/dart/latest/_util-fns.jade index 380b4ac7a1..98be78138f 100644 --- a/public/docs/dart/latest/_util-fns.jade +++ b/public/docs/dart/latest/_util-fns.jade @@ -14,12 +14,16 @@ include ../../../_includes/_util-fns - var _liveLink = 'sample repo'; mixin liveExampleLink(linkText, exampleUrlPartName) - a(href='https://angular-examples.github.io/#{exampleUrlPartName}' target="_blank")= linkText + - var text = linkText || 'live example'; + - var ex = exampleUrlPartName || getExampleName(); + - var href = 'http://angular-examples.github.io/' + ex; + a(href='#{href}' target="_blank")= text mixin liveExampleLink2(linkText, exampleUrlPartName) - - var liveExampleSourceLinkText = attributes.srcLinkText || 'view source' - | #[+liveExampleLink(linkText, exampleUrlPartName)] - | (#[a(href='https://github.com/angular-examples/#{exampleUrlPartName}' target="_blank") #{liveExampleSourceLinkText}]) + - var srcText = attributes.srcText || 'view source'; + - var ex = exampleUrlPartName || attributes.example || getExampleName(); + - var href = 'http://github.com/angular-examples/' + ex; + span #[+liveExampleLink(linkText, ex)] (#[a(href='#{href}' target="_blank") #{srcText}]) - var adjustExamplePath = function(_path) { - if(!_path) return _path; diff --git a/public/docs/dart/latest/cookbook/_data.json b/public/docs/dart/latest/cookbook/_data.json index 2c28e02169..9b2545ec5e 100644 --- a/public/docs/dart/latest/cookbook/_data.json +++ b/public/docs/dart/latest/cookbook/_data.json @@ -17,6 +17,12 @@ "intro": "Share information between different directives and components" }, + "component-relative-paths": { + "title": "Component-relative Paths", + "intro": "Use relative URLs for component templates and styles.", + "hide": true + }, + "dependency-injection": { "title": "Dependency Injection", "intro": "Techniques for Dependency Injection", diff --git a/public/docs/dart/latest/cookbook/component-relative-paths.jade b/public/docs/dart/latest/cookbook/component-relative-paths.jade new file mode 100644 index 0000000000..6778b6af28 --- /dev/null +++ b/public/docs/dart/latest/cookbook/component-relative-paths.jade @@ -0,0 +1 @@ +!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/dart/latest/guide/_data.json b/public/docs/dart/latest/guide/_data.json index fe30a34965..4b6553b64d 100644 --- a/public/docs/dart/latest/guide/_data.json +++ b/public/docs/dart/latest/guide/_data.json @@ -80,8 +80,8 @@ }, "server-communication": { - "title": "Http Client", - "intro": "Talk to a remote server with the Angular Http Client." + "title": "HTTP Client", + "intro": "Talk to a remote server with an HTTP Client." }, "lifecycle-hooks": { diff --git a/public/docs/dart/latest/guide/server-communication.jade b/public/docs/dart/latest/guide/server-communication.jade index 0195d5cb88..51bd3a63db 100644 --- a/public/docs/dart/latest/guide/server-communication.jade +++ b/public/docs/dart/latest/guide/server-communication.jade @@ -5,11 +5,11 @@ block includes - var _Http = 'BrowserClient'; - var _Angular_Http = 'Dart BrowserClient' - var _httpUrl = 'https://pub.dartlang.org/packages/http' - - var _Angular_http_library = 'Dart http library' + - var _Angular_http_library = 'Dart http library' block demos-list - li HTTP client: Tour of Heroes - li JSONP client: Wikipedia to fetch data from a service that doesn't support CORS (under development) + li #[a(href="#http-client") HTTP client: Tour of Heroes] + li #[a(href="#cors") JSONP client: Wikipedia to fetch data from a service that does not support CORS] #[b (under development)] block rxjs-import //- N/A diff --git a/public/docs/js/latest/cookbook/_data.json b/public/docs/js/latest/cookbook/_data.json index f4f89de38c..2d9ada59f1 100644 --- a/public/docs/js/latest/cookbook/_data.json +++ b/public/docs/js/latest/cookbook/_data.json @@ -16,6 +16,11 @@ "intro": "Share information between different directives and components" }, + "component-relative-paths": { + "title": "Component-relative Paths", + "intro": "Use relative URLs for component templates and styles." + }, + "dependency-injection": { "title": "Dependency Injection", "intro": "Techniques for Dependency Injection" diff --git a/public/docs/js/latest/cookbook/component-relative-paths.jade b/public/docs/js/latest/cookbook/component-relative-paths.jade new file mode 100644 index 0000000000..6778b6af28 --- /dev/null +++ b/public/docs/js/latest/cookbook/component-relative-paths.jade @@ -0,0 +1 @@ +!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/js/latest/guide/_data.json b/public/docs/js/latest/guide/_data.json index 62a168eae5..59ba8dfd01 100644 --- a/public/docs/js/latest/guide/_data.json +++ b/public/docs/js/latest/guide/_data.json @@ -80,8 +80,8 @@ }, "server-communication": { - "title": "Http Client", - "intro": "Talk to a remote server with the Angular Http Client." + "title": "HTTP Client", + "intro": "Talk to a remote server with an HTTP Client." }, "lifecycle-hooks": { diff --git a/public/docs/ts/latest/_util-fns.jade b/public/docs/ts/latest/_util-fns.jade index 5c3d720cf3..e31e48af09 100644 --- a/public/docs/ts/latest/_util-fns.jade +++ b/public/docs/ts/latest/_util-fns.jade @@ -5,8 +5,11 @@ include ../../../_includes/_util-fns //- Other values match the defaults. mixin liveExampleLink(linkText, exampleUrlPartName) - a(href='/resources/live-examples/#{exampleUrlPartName}/ts/plnkr.html' target="_blank")= linkText + - var text = linkText || 'live example'; + - var ex = exampleUrlPartName || getExampleName(); + - var href = '/resources/live-examples/' + ex + '/ts/plnkr.html'; + a(href='#{href}' target="_blank")= text mixin liveExampleLink2(linkText, exampleUrlPartName) - //- In Dart this also gives a link to the source. - | #[+liveExampleLink(linkText, exampleUrlPartName)] + //- In Dart this gives 2 links: to the demo and to the source. + +liveExampleLink(linkText, exampleUrlPartName) diff --git a/public/docs/ts/latest/cookbook/_data.json b/public/docs/ts/latest/cookbook/_data.json index e1f0fab46e..d119bcab5a 100644 --- a/public/docs/ts/latest/cookbook/_data.json +++ b/public/docs/ts/latest/cookbook/_data.json @@ -15,6 +15,12 @@ "title": "组件通讯", "intro": "在不同的指令和组件之间共享信息" }, + + "component-relative-paths": { + "title": "相对于组件的路径", + "intro": "为组件的模板和样式指定相对于组件的路径" + }, + "dependency-injection": { "title": "依赖注入", "intro": "依赖注入技术" diff --git a/public/docs/ts/latest/cookbook/component-relative-paths.jade b/public/docs/ts/latest/cookbook/component-relative-paths.jade new file mode 100644 index 0000000000..66f90c1ffd --- /dev/null +++ b/public/docs/ts/latest/cookbook/component-relative-paths.jade @@ -0,0 +1,140 @@ +include ../_util-fns + +:marked + ## Write *Component-Relative* URLs to component templates and style files + + Our components ofter refer to external template and style files. + We identify those files with a URL in the `templateUrl` and `styleUrls` properties of the `@Component` metadata + as seen here: + ++makeExample('cb-component-relative-paths/ts/app/some.component.ts','absolute-config')(format='.') +:marked + By default, we *must* specify the full path back to the application root. + We call this an ***absolute path*** because it is *absolute* with respect to the application root. + + There are two problems with an *absolute path* + + 1. We have to remember the full path back to the application root. + + 1. We have to update the URL when we move the component around in the application files structure. + + It would be much easier to write and maintain our application components if we could specify template and style locations + *relative* to their component class file. + + *We can!* + +.alert.is-important + :marked + We can if we build our application as `commonjs` modules and load those modules + with a suitable package loader such as `systemjs` or `webpack`. + Learn why [below](#why-default). + + The Angular 2 CLI uses these technologies and defaults to the + *component-relative path* approach described here. + CLI users can skip this chapter or read on to understand + how it works. + +.l-main-section +:marked + ## _Component-Relative_ Paths + + Our goal is to specify template and style URLs *relative* to their component class files, + hence the term ***component-relative path***. + + The key to success is following a convention that puts related component files in well-known locations. + + We recommend keeping component template and component-specific style files as *siblings* of their + companion component class files. + Here we see the three files for `SomeComponent` sitting next to each other in the `app` folder. + +.filetree + .file app + .children + .file some.component.css + .file some.component.html + .file some.component.ts + .file ... +:marked + We'll have more files and folders — and greater folder depth — as our application grows. + We'll be fine as long as the component files travel together as the inseparable siblings they are. + + ### Set the *moduleId* + + Having adopted this file structure convention, we can specify locations of the template and style files + relative to the component class file simply by setting the `moduleId` property of the `@Component` metadata like this ++makeExample('cb-component-relative-paths/ts/app/some.component.ts','module-id')(format='.') +:marked + We strip the `app/` base path from the `templateUrl` and `styleUrls`. The result looks like this: ++makeExample('cb-component-relative-paths/ts/app/some.component.ts','relative-config')(format='.') + +.alert.is-helpful + :marked + Webpack users may prefer [an alternative approach](#webpack) that uses `require`. + +.l-main-section +:marked + ## Source + + **We can see the [live example](/resources/live-examples/cb-component-relative-paths/ts/plnkr.html)** + and download the source code from there + or simply read the pertinent source here. ++makeTabs( + `cb-component-relative-paths/ts/app/some.component.ts, + cb-component-relative-paths/ts/app/some.component.html, + cb-component-relative-paths/ts/app/some.component.css, + cb-component-relative-paths/ts/app/app.component.ts`, + null, + `app/some.component.ts, app/some.component.html, app/some.component.css, app/app.component.ts`) + +a#why-default +.l-main-section +:marked + ## Appendix: why *component-relative* is not the default + + A *component-relative* path is obviously superior to an *absolute* path. + Why did Angular default to the *absolute* path? + Why do *we* have to set the `moduleId`? Why can't Angular set it? + + First, let's look at what happens if we use a relative path and omit the `moduleId`. + + `EXCEPTION: Failed to load some.component.html` + + Angular can't find the file so it throws an error. + + Why can't Angular calculate the template and style URLs from the component file's location? + + Because the location of the component can't be determined without the developer's help. + Angular apps can be loaded in many ways: from individual files, from SystemJS packages, or + from CommonJS packages, to name a few. + We might generate modules in any of several formats. + We might not be writing modular code at all! + + With this diversity of packaging and module load strategies, + it's not possible for Angular to know with certainty where these files reside at runtime. + + The only location Angular can be sure of is the URL of the `index.html` home page, the application root. + So by default it resolves template and style paths relative to the URL of `index.html`. + That's why we previously wrote our file URLs with an `app/` base path prefix. + + But *if* we follow the recommended guidelines and we write modules in `commonjs` format + and we use a module loader that *plays nice*, + *then* we — the developers of the application — + know that the semi-global `module.id` variable is available and contains + the absolute URL of the component class module file. + + That knowledge enables us to tell Angular where the *component* file is + by setting the `moduleId`: ++makeExample('cb-component-relative-paths/ts/app/some.component.ts','module-id')(format='.') + +a#webpack +.l-main-section +:marked + ## Webpack: load templates and styles with *require* + Webpack developers have an alternative to `moduleId`. + + They can load templates and styles at runtime by setting the component metadata `template` and `style` properties + with `require` statements that reference *component-relative* URLS. + ++makeExample('webpack/ts/src/app/app.component.ts')(format='.') +:marked + See the [Introduction to Webpack](../guide/webpack.html). diff --git a/public/docs/ts/latest/guide/_data.json b/public/docs/ts/latest/guide/_data.json index eb58a24234..04200202ba 100644 --- a/public/docs/ts/latest/guide/_data.json +++ b/public/docs/ts/latest/guide/_data.json @@ -80,8 +80,8 @@ }, "server-communication": { - "title": "Http客户端", - "intro": "通过Angular Http客户端与远程服务器对话。" + "title": "HTTP客户端", + "intro": "通过HTTP客户端与远程服务器对话。" }, "lifecycle-hooks": { diff --git a/public/docs/ts/latest/guide/attribute-directives.jade b/public/docs/ts/latest/guide/attribute-directives.jade index 6391b18c2b..7fb0d7fcf7 100644 --- a/public/docs/ts/latest/guide/attribute-directives.jade +++ b/public/docs/ts/latest/guide/attribute-directives.jade @@ -19,8 +19,8 @@ block includes * [pass values into the directive using data binding](#bindings) * [使用数据绑定把值传到指令中](#bindings) -p. - #[+liveExampleLink2('在线例子', 'attribute-directives')]. +p Try the #[+liveExampleLink2()]. + :marked ## Directives overview ## 指令概览 diff --git a/public/docs/ts/latest/guide/component-styles.jade b/public/docs/ts/latest/guide/component-styles.jade index be2838650b..f20038b6d5 100644 --- a/public/docs/ts/latest/guide/component-styles.jade +++ b/public/docs/ts/latest/guide/component-styles.jade @@ -32,12 +32,9 @@ block includes * [Appendix 1: Inspecting the generated runtime component styles](#inspect-generated-css) * [附录1: 审查生成的运行时组件样式](#inspect-generated-css) * [Appendix 2: Loading Styles with Relative URLs](#relative-urls) - * [附录2: 用相对URL加载样式](#relative-urls) -p - | #[+liveExampleLink2('Run the live example', 'component-styles')]  - | of the code shown in this chapter. -p - | #[+liveExampleLink2('运行本章代码的在线范例', 'component-styles')] + +p Run the #[+liveExampleLink2()] of the code shown in this chapter. +p 运行本章这些代码的#[+liveExampleLink2()] .l-main-section :marked @@ -473,96 +470,12 @@ code-example(format=''). block module-id :marked - We'd *prefer* to write this: + We can change the way Angular calculates the full URL be setting the component metadata's `moduleId` property to `module.id`. - 我们期望的*首选*方式是这样写: - - +makeExample('component-styles/ts/app/quest-summary.component.ts', 'urls')(format='.') - - :marked - We can't do that by default. Angular can't find the files and throws an error: - - 但默认情况下我们不能这么做。Angular找不到这个文件,并且抛出一个错误: - - `EXCEPTION: Failed to load quest-summary.component.html` - - `异常:不能加载quest-summary.component.html文件(EXCEPTION: Failed to load quest-summary.component.html)` - - Why can't Angular calculate the HTML and CSS URLs from the component file's location? - - 为什么Angular不能根据组件文件的位置计算出HTML和CSS文件的URL呢? - - Unfortunately, that location is not readily known. - Angular apps can be loaded in many ways: from individual files, from SystemJS packages, or - from CommonJS packages, to name a few. - With this diversity of load strategies, it's not easy to tell at runtime where these files actually reside. - - 很不幸,当前的位置并不是已知的。 - Angular应用可以用多种方式被加载:从独立的文件、从SystemJS包,或从CommonJS包等等。 - 由于存在这么多种加载策略,要想在运行期知道这些文件的实际位置,可不是一件容易的事。 - - The only location Angular can be sure of is the URL of the `index.html` home page. - So by default it resolves template and style paths relative to the URL of `index.html`. - That's why we previously wrote our CSS file URLs with an `app/` base path prefix. - - Angular唯一能够确定的位置,就是起始页`index.html`的URL。 - 所以,默认情况下,它都是以`index.html`的URL为基准来计算模板和样式的相对路径的。 - 这就是为什么我们以前写自身CSS文件的URL都以`app/`基本路径作为前缀。 - - Although this works with any code loading scheme, it is very inconvenient. - We move file folders around all the time during the evolution of our applications. - It's no fun patching the style and template URLs when we do. - - 虽然这能够和各种代码加载方案协同工作,但它很不方便。 - 在应用程序的进化过程中,我们经常要移动文件夹。整天被迫修改样式和模板的URL可一点儿都不好玩儿! - - ### *moduleId* - ### *moduleId* - - We can change the way Angular calculates the full URL be setting the component metadata's `moduleId` property. - - 我们可以通过设置组件元数据中的`moduleId`属性,我们可以改变Angular计算完整URL的方式。 - - If we knew the component file's base path, we'd set `moduleId` to that and - let Angular construct the full URL from this base path plus the CSS and template file names. - - 如果我们知道组件文件的基本路径,我们就可以把`moduleId`设置成它, - 让Angular可以用这个基本路径加上CSS和模板文件的名字来构造出完整URL。 - - Our challenge is to calculate the base path with minimal effort. - If it's too hard, we shouldn't bother; we should just write the full path to the root and move on. - Fortunately, *certain* module loaders make it relatively easy to find the base path. - - 我们的挑战是如何用最小的代价计算出这个基本路径。 - 如果太难,我们也不想自找麻烦,还不如直接写到程序根目录的全路径,然后继续。 - 幸运的是,在*某些*模块加载器中找到基本路径要相对简单一些。 - - SystemJS (starting in v.0.19.19) sets a *semi-global* variable to the URL of the component file. - That makes it trivial to set the component metadata `moduleId` property to the component's URL - and let Angular determine the module-relative paths for style and template URLs from there. - - SystemJS(自从v.0.19.19起)设置了一个*半全局*变量来指向组件文件的URL。 - 有了它,把组件元数据的`moduleId`属性设置为组件本身的URL就简单多了, - 这样Angular就能让样式和模板的URL使用相对于模块的路径。 - - The name of the *semi-global* variable depends upon whether we told TypeScript to transpile to - 'system' or 'commonjs' format (see the `module` option in the - [TypeScript compiler documentation](http://www.typescriptlang.org/docs/handbook/compiler-options.html)). - The variables are `__moduleName` and `module.id` respectively. - - 这个*半全局*变量的名字取决于我们是告诉TypeScript转译成'system'还是'commonjs'格式 - (参见[TypeScript编译器文档](http://www.typescriptlang.org/docs/handbook/compiler-options.html)中的`module`选项)。 - 这个变量分别是`__moduleName`(system格式)和`module.id`(commonjs格式)。 - - Here's an example in which we set the metadata `moduleId` to `module.id`. - - 下面的例子中示范了我们如何把元数据中的`moduleId`设置为`module.id`。 + 通过把组件元数据的`moduleId`属性设置为`module.id`,我们可以更改Angular计算完整URL的方式 +makeExample('component-styles/ts/app/quest-summary.component.ts','', 'app/quest-summary.component.ts') - - .l-sub-section - :marked - With a module bundler like Webpack we are more likely to set the `styles` and `template` properties with the bundler's - `require` mechanism rather than bother with `styleUrls` and `templateUrl`. - - 如果使用像Webpack这样的模块打包器,我们更喜欢借助打包器本身的`require`机制来设置`styles`和`template`属性,而不是`styleUrls`和`templateUrl`。 + :marked + Learn more about `moduleId` in the [Component-Relative Paths](../cookbook/component-relative-paths.html) chapter. + + 要学习更多关于`moduleId`的知识,请参见[相对于组件的路径](../cookbook/component-relative-paths.html)一章。 diff --git a/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade b/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade index 07ce723d88..4393fc3c17 100644 --- a/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade +++ b/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade @@ -20,8 +20,9 @@ block includes In this chapter we explore these points and write some code. 在本章中,我们将浏览这些要点,并写点代码儿来验证它。 -p - | Try the #[+liveExampleLink2('live example', 'hierarchical-dependency-injection')]. + +p Try the #[+liveExampleLink2()]. +p 试试#[+liveExampleLink2()]. .l-main-section :marked diff --git a/public/docs/ts/latest/guide/lifecycle-hooks.jade b/public/docs/ts/latest/guide/lifecycle-hooks.jade index 903160ca97..f29ffc40d2 100644 --- a/public/docs/ts/latest/guide/lifecycle-hooks.jade +++ b/public/docs/ts/latest/guide/lifecycle-hooks.jade @@ -24,7 +24,7 @@ block includes * [AfterViewInit and AfterViewChecked](#afterview) * [AfterContentInit and AfterContentChecked](#aftercontent) -p Try the #[+liveExampleLink2('live example', 'lifecycle-hooks')]. +p Try the #[+liveExampleLink2()]. a#hooks-overview .l-main-section @@ -199,7 +199,7 @@ a#the-sample .l-main-section h2 Lifecycle exercises p. - The #[+liveExampleLink('live example', 'lifecycle-hooks')] + The #[+liveExampleLink()] demonstrates the lifecycle hooks in action through a series of exercises presented as components under the control of the root `AppComponent`. :marked diff --git a/public/docs/ts/latest/guide/pipes.jade b/public/docs/ts/latest/guide/pipes.jade index 4fa76296bc..1f453d0a29 100644 --- a/public/docs/ts/latest/guide/pipes.jade +++ b/public/docs/ts/latest/guide/pipes.jade @@ -17,7 +17,7 @@ block includes In fact, we'd like to apply them in our HTML templates as we do styles. p. Welcome, Angular pipes, the simple display-value transformations that we can declare in our HTML! - Try the #[+liveExampleLink2('live example', 'pipes')]. + Try the #[+liveExampleLink2()]. .l-main-section :marked @@ -169,7 +169,7 @@ figure.image-display Custom pipes must be registered manually. p. - If we try the #[+liveExampleLink('live code', 'pipes')] example, + If we try the #[+liveExampleLink()], we can probe its behavior by changing the value and the optional exponent in the template. :marked @@ -219,10 +219,10 @@ a#change-detection Here's the `FlyingHeroesPipe` implementation which follows the pattern for custom pipes we saw earlier. +makeExample('pipes/ts/app/flying-heroes.pipe.ts', 'pure', 'app/flying-heroes.pipe.ts')(format='.') -:marked - When we run the sample now we see odd behavior (try it in the [live example](/resources/live-examples/pipes/ts/plnkr.html)). +p. + When we run the sample now we see odd behavior (try it in the #[+liveExampleLink()]). Every hero we add is a flying hero but none of them are displayed. - +:marked Although we're not getting the behavior we want, Angular isn't broken. It's just using a different change detection algorithm — one that ignores changes to the list or any of its items. @@ -238,7 +238,7 @@ a#change-detection *If we **mutate** the #{_array}, no pipe is invoked and no display updated; if we **replace** the #{_array}, then the pipe executes and the display is updated*. - The *Flying Heroes* in the [live example](/resources/live-examples/pipes/ts/plnkr.html) extends the + The *Flying Heroes* extends the code with checkbox switches and additional displays to help us experience these effects. figure.image-display @@ -328,15 +328,15 @@ block pure-change We can derive a `FlyingHeroesImpureComponent` that we derive from the `FlyingHeroesComponent`. +makeExample('pipes/ts/app/flying-heroes.component.ts','impure-component','app/flying-heroes.component.ts (FlyingHeroesImpureComponent)')(format='.') -:marked +p. The only substantive change is the pipe. - We can confirm in the [live example](/resources/live-examples/pipes/ts/plnkr.html) - that the *flying heroes* display updates as we enter new heroes even when we mutate the `heroes` #{_array}. -- var _dollar = _docsFor === 'ts' ? '$' : ''; -:marked - - ### The impure *AsyncPipe* + We can confirm in the #[+liveExampleLink()] that the #[i flying heroes] + display updates as we enter new heroes even when we mutate the + #[code heroes] #{_array}. +- var _dollar = _docsFor === 'ts' ? '$' : ''; +h3#async-pipe The impure #[i AsyncPipe] +:marked The Angular `AsyncPipe` is an interesting example of an impure pipe. The `AsyncPipe` accepts a `#{_Promise}` or `#{_Observable}` as input and subscribes to the input automatically, eventually returning the emitted value(s). diff --git a/public/docs/ts/latest/guide/server-communication.jade b/public/docs/ts/latest/guide/server-communication.jade index eea4772a11..e24020f77c 100644 --- a/public/docs/ts/latest/guide/server-communication.jade +++ b/public/docs/ts/latest/guide/server-communication.jade @@ -16,7 +16,7 @@ block includes [JSONP](https://en.wikipedia.org/wiki/JSONP). A few browsers also support [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). - The Angular HTTP client library simplifies application programming of the **XHR** and **JSONP** APIs + The !{_Angular_http_library} simplifies application programming of the **XHR** and **JSONP** APIs as we'll learn in this chapter covering: ul @@ -30,25 +30,25 @@ ul li #[a(href="#update") Send data to the server] +ifDocsFor('ts') li #[a(href="#promises") Promises instead of observables] - li #[a(href="#cross-origin-requests") Cross-origin requests: Wikipedia example] + li #[a(href="#cors") Cross-origin requests: Wikipedia example] +ifDocsFor('ts') ul li #[a(href="#search-parameters") Set query string parameters] li #[a(href="#more-observables") Debounce search term input] li #[a(href="#in-mem-web-api") Appendix: the in-memory web api service] -p. +p. We illustrate these topics with code that you can - #[+liveExampleLink2('run live in a browser', 'server-communication')]. + #[+liveExampleLink2('run live in a browser')]. .l-main-section h1 Demos p This chapter describes server communication with the help of the following demos ul block demos-list - li HTTP client: Tour of Heroes with Observables - li HTTP client: Tour of Heroes with #{_Promise}s - li JSONP client: Wikipedia to fetch data from a service that doesn't support CORS - li JSONP client: Wikipedia using observable operators to reduce server calls + li #[a(href="#http-client") HTTP client: Tour of Heroes with Observables] + li #[a(href="#promises") HTTP client: Tour of Heroes with #{_Promise}s] + li #[a(href="#cors") JSONP client: Wikipedia to fetch data from a service that does not support CORS] + li #[a(href="#more-observables") JSONP client: Wikipedia using observable operators to reduce server calls] :marked These demos are orchestrated by the root `AppComponent` +makeExample('server-communication/ts/app/app.component.ts', null, 'app/app.component.ts') @@ -58,7 +58,7 @@ block rxjs-import There is nothing remarkable here _except_ for the import of RxJS operators. +makeExample('server-communication/ts/app/app.component.ts', 'import-rxjs')(format='.') :marked - We'll talk about that [below](#rxjs) when we're ready to explore observables. + We'll talk about that [below](#rxjs) when we're ready to explore observables. :marked First, we have to configure our application to use server communication facilities. @@ -66,14 +66,14 @@ block rxjs-import h1#http-providers Providing HTTP Services :marked We use the !{_Angular_Http} client to communicate with a server using a familiar HTTP request/response protocol. - The `!{_Http}` client is one of a family of services in the !{_Angular_http_library}. + The `#{_Http}` client is one of a family of services in the !{_Angular_http_library}. block system-config-of-http .l-sub-section :marked SystemJS knows how to load services from the !{_Angular_http_library} when we import from the `@angular/http` module because we registered that module name in the `system.config` file. :marked - Before we can use the `!{_Http}` client , we'll have to register it as a service provider with the Dependency Injection system. + Before we can use the `#{_Http}` client , we'll have to register it as a service provider with the Dependency Injection system. .l-sub-section :marked Learn about providers in the [Dependency Injection](dependency-injection.html) chapter. @@ -84,7 +84,7 @@ p In this demo, we register providers in the #[code bootstrap] method of #[code block http-providers :marked We begin by importing the symbols we need, most of them familiar by now. The newcomer is `HTTP_PROVIDERS`, - a collection of service providers from the Angular HTTP library. + a collection of service providers from the !{_Angular_http_library}. We register HTTP providers in the bootstrap method by passing them in an array as the second parameter after the root component. @@ -105,10 +105,8 @@ block http-providers For this reason, and this reason *only*, we hide it *above* the `AppComponent` in `main.ts`. .l-main-section -a#http-client +h1#http-client The Tour of Heroes #[i HTTP] Client Demo :marked - # The Tour of Heroes *HTTP* Client Demo - Our first demo is a mini-version of the [tutorial](../tutorial)'s "Tour of Heroes" (ToH) application. This version gets some heroes from the server, displays them in a list, lets us add new heroes, and saves them to the server. We use the !{_Angular_Http} client to communicate via `XMLHttpRequest (XHR)`. @@ -182,7 +180,7 @@ h2#fetch-data Fetch data with the #[b HeroService] +makeExample('server-communication/ts/app/toh/hero.service.ts', 'v1', 'app/toh/hero.service.ts (revised)') :marked - Notice that the Angular `!{_Http}` client service is + Notice that the !{_Angular_Http} client service is [injected](dependency-injection.html) into the `HeroService` constructor. +makeExample('server-communication/ts/app/toh/hero.service.ts', 'ctor') :marked @@ -237,7 +235,7 @@ block rxjs because the full library is so big. We only use a few operators in our app. Instead, we'll import each `Observable` operator and static class method, one-by-one, until we have a custom *Observable* implementation tuned - precisely to our requirements. We'll put the `import` statements in one `app/add-rxjs-operators.ts` file. + precisely to our requirements. We'll put the `import` statements in one `app/rxjs-operators.ts` file. +makeExample('server-communication/ts/app/rxjs-operators.ts', null, 'app/rxjs-operators.ts')(format=".") :marked If we forget an operator, the TypeScript compiler will warn that it's missing and we'll update this file. @@ -412,10 +410,8 @@ block hero-list-comp-add-hero +makeExample('server-communication/ts/app/toh/hero-list.component.ts', 'addHero', 'app/toh/hero-list.component.ts (addHero)')(format=".") block promises - a#promises + h2#promises Fall back to Promises :marked - ## Fall back to Promises - Although the Angular `http` client API returns an `Observable` we can turn it into a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) if we prefer. It's easy to do and a promise-based version looks much like the observable-based version in simple cases. @@ -461,11 +457,9 @@ block promises Learn more about observables to understand the implications and consequences of subscriptions. -a#cross-origin-requests +h2#cors Cross-origin requests: Wikipedia example :marked - ## Cross-origin requests: Wikipedia example - - We just learned how to make `XMLHttpRequests` using Angular's built-in `Http` service. + We just learned how to make `XMLHttpRequests` using the !{_Angular_Http} service. This is the most common approach for server communication. It doesn't work in all scenarios. @@ -496,7 +490,7 @@ figure.image-display block wikipedia-jsonp+ :marked Wikipedia offers a modern `CORS` API and a legacy `JSONP` search API. Let's use the latter for this example. - The Angular `Jsonp` service both extends the `Http` service for JSONP and restricts us to `GET` requests. + The Angular `Jsonp` service both extends the `#{_Http}` service for JSONP and restricts us to `GET` requests. All other HTTP methods throw an error because JSONP is a read-only facility. As always, we wrap our interaction with an Angular data access client service inside a dedicated service, here called `WikipediaService`. @@ -638,7 +632,7 @@ block wikipedia-jsonp+ .l-sub-section :marked We added the `debounceTime`, `distinctUntilChanged`, and `switchMap` operators to the RxJS `Observable` class - in `add-rxjs-operators` as [described above](#rxjs) + in `rxjs-operators` as [described above](#rxjs) a#in-mem-web-api .l-main-section @@ -694,4 +688,4 @@ block redirect-to-web-api p Here is the revised (and final) version of the #[code #[+adjExPath('app/main.ts')]] demonstrating these steps. +makeExample('server-communication/ts/app/main.ts', 'final', 'app/main.ts (final)')(format=".") -p See the full source code in the #[+liveExampleLink2('live example', 'server-communication')]. +p See the full source code in the #[+liveExampleLink2()]. diff --git a/public/docs/ts/latest/guide/structural-directives.jade b/public/docs/ts/latest/guide/structural-directives.jade index c69cc870c0..54fb395ee6 100644 --- a/public/docs/ts/latest/guide/structural-directives.jade +++ b/public/docs/ts/latest/guide/structural-directives.jade @@ -14,8 +14,8 @@ block includes - [discover the <template> element](#template) - [understand the asterisk (\*) in **ngFor*](#asterisk) - [write our own structural directive](#unless) -p - | Try the #[+liveExampleLink2('live example', 'structural-directives')]. + +p Try the #[+liveExampleLink2()]. .l-main-section diff --git a/public/docs/ts/latest/guide/style-guide.jade b/public/docs/ts/latest/guide/style-guide.jade index c677e62294..718490b2ac 100644 --- a/public/docs/ts/latest/guide/style-guide.jade +++ b/public/docs/ts/latest/guide/style-guide.jade @@ -496,9 +496,9 @@ a(href="#toc") 回到顶部 .s-why :marked - **Why?** Clear service names such as `logger` do not require a suffix. + **Why?** Clear service names such as `Logger` do not require a suffix. - **为何?**清楚的服务名,比如`logger`不需要后缀。 + **为何?**清楚的服务名,比如`Logger`不需要后缀。 .s-why.s-why-last :marked @@ -537,7 +537,7 @@ table(width="100%") td code-example. @Injectable() - export class LoggerService {} + export class Logger {} td :marked logger.service.ts diff --git a/public/docs/ts/latest/quickstart.jade b/public/docs/ts/latest/quickstart.jade index 5f7f1a6ba5..00b2140d9f 100644 --- a/public/docs/ts/latest/quickstart.jade +++ b/public/docs/ts/latest/quickstart.jade @@ -33,7 +33,7 @@ block includes h1 Try it! h1 试试! p - | Try the #[+liveExampleLink2('live example', 'quickstart')] which loads the sample app + | Try the #[+liveExampleLink2()] which loads the sample app +ifDocsFor('ts') |  in #[a(href="http://plnkr.co/" title="Plunker" target="_blank") plunker] |  and displays the simple message: diff --git a/public/docs/ts/latest/tutorial/toh-pt3.jade b/public/docs/ts/latest/tutorial/toh-pt3.jade index 1194234018..134a0981be 100644 --- a/public/docs/ts/latest/tutorial/toh-pt3.jade +++ b/public/docs/ts/latest/tutorial/toh-pt3.jade @@ -268,7 +268,7 @@ code-example(format="."). `AppComponent`的模板是这样的: -+makeExample('toh-3/ts/app/app.component.ts', 'hero-detail-template', 'app.component.ts (模板)') ++makeExample('toh-3/ts/app/app.component.ts', 'hero-detail-template', 'app.component.ts (Template)')(format='.') :marked Thanks to the binding, the `HeroDetailComponent` should receive the hero from the `AppComponent` and display that hero's detail beneath the list. The detail should update every time the user picks a new hero. @@ -302,9 +302,7 @@ code-example(format="."). 我们要把它列在元数据的`directives`数组中,这样Angular才会知道它。 让我们把这个数组属性加在`@Component`配置对象的底部,紧跟在`template`和`styles`属性之后。 - -+makeExample('toh-3/ts/app/app.component.ts', 'directives') - ++makeExample('toh-3/ts/app/app.component.ts', 'directives', 'app/app.component.ts (Directives)') :marked ### It works! @@ -340,7 +338,7 @@ code-example(format="."). .file hero-detail.component.ts .file main.ts .file node_modules ... - .file typings ... + .file typings ... .file index.html .file package.json .file tsconfig.json diff --git a/public/docs/ts/latest/tutorial/toh-pt4.jade b/public/docs/ts/latest/tutorial/toh-pt4.jade index 03270168bd..4162551dbe 100644 --- a/public/docs/ts/latest/tutorial/toh-pt4.jade +++ b/public/docs/ts/latest/tutorial/toh-pt4.jade @@ -270,7 +270,7 @@ code-example(format="." language="bash"). ### Inject the *HeroService* ### 注入 *HeroService* - Two lines replace the one line of *new*: + Two lines replace the one line that created with *new*: 用这两行代码代替用`new`时的一行: 1. we add a constructor. @@ -292,15 +292,6 @@ code-example(format="." language="bash"). 现在,Angular将会知道,当它创建`AppComponent`实例时,需要先提供一个`HeroService`的实例。 - Angular has to get that instance from somewhere. That's the role of the Angular *Dependency Injector*. - The **Injector** has a **container** of previously created services. - Either it finds and returns a pre-existing `HeroService` from its container or it creates a new instance, adds - it to the container, and returns it to Angular. - - Angular得想办法获得这个实例。这就是Angular *依赖注入器(Dependency Injector)* 扮演的角色。 - 这个 **注入器** 有一个包括以前创建过的所有服务的 **容器** 。 - 它既可以从容器中查找并返回一个已存在的`HeroService`实例,又可以创建一个新的实例,把它添加到容器中,然后把它返回给Angular。 - .l-sub-section :marked Learn more about Dependency Injection in the [Dependency Injection](../guide/dependency-injection.html) chapter. @@ -328,35 +319,7 @@ code-example(format="." language="html"). :marked The `providers` array tells Angular to create a fresh instance of the `HeroService` when it creates a new `AppComponent`. The `AppComponent` can use that service to get heroes and so can every child component of its component tree. - - `providers`数组告诉Angular,在创建一个新的`AppComponent`时,也要创建一个`HeroService`的新鲜实例。 - `AppComponent`可以用此服务来获取英雄列表,它组件树中的每一个子组件也可以这么做。 - -.l-sub-section - :marked - ### Services and the component tree - ### 服务和组件树 - - Recall that the `AppComponent` creates an instance of `HeroDetail` by virtue of the - `` tag at the bottom of its template. That `HeroDetail` is a child of the `AppComponent`. - - 回忆一下,`AppComponent`在它的模板底部包含了一个``标签,于是创建了一个`HeroDetail`的实例。这个`HeroDetail`就叫做`AppComponent`的子组件。 - - If the `HeroDetailComponent` needed its parent component's `HeroService`, - it would ask Angular to inject the service into its constructor which would look just like the one for `AppComponent`: - - 如果`HeroDetailComponent`需要访问来自它父组件的`HeroService`服务,它可以要求Angular把这个服务注入到自己的构造函数中 —— 就像在`AppComponent`中的做法一样。 - - +makeExample('toh-4/ts/app/app.component.1.ts', 'ctor', 'hero-detail.component.ts (构造函数)') - :marked - The `HeroDetailComponent` must *not* repeat its parent's `providers` array! Guess [why](#shadow-provider). - - `HeroDetailComponent`不能再写一遍它父组件的`providers`数组!你猜这是[为什么](#shadow-provider)。 - - The `AppComponent` is the top level component of our application. - There should be only one instance of that component and only one instance of the `HeroService` in our entire app. - - `AppComponent`是我们应用的顶层组件。在我们的整个应用中,应该有唯一的一个顶层组件,应该有唯一的一个`HeroService`实例。 +a#child-component :marked ### *getHeroes* in the *AppComponent* ### *AppComponent* 中的 *getHeroes* @@ -629,30 +592,3 @@ code-example(format="." language="html"). Back in the `AppComponent`, replace `heroService.getHeroes` with `heroService.getHeroesSlowly` and see how the app behaves. - - 回到`AppComponent`中,把`heroService.getHeroes`替换为`heroService.getHeroesSlowly`,看看应用的行为有什么变化。 - -.l-main-section - -:marked - ### Appendix: Shadowing the parent's service - ### 附件:遮蔽父组件的服务 - - We stated [earlier](#child-component) that if we injected the parent `AppComponent` `HeroService` - into the `HeroDetailComponent`, *we must not add a providers array* to the `HeroDetailComponent` metadata. - - 我们在[前面](#child-component)说过,如果在父组件`AppComponent`中把`HeroService`服务注入到`HeroDetailComponent`, - *我们就不应该在`HeroDetailComponent`的元数据中再添加一个`providers`数组*。 - - Why? Because that tells Angular to create a new instance of the `HeroService` at the `HeroDetailComponent` level. - The `HeroDetailComponent` doesn't want its *own* service instance; it wants its *parent's* service instance. - Adding the `providers` array creates a new service instance that shadows the parent instance. - - 为什么呢?因为那会告诉Angular在`HeroDetailComponent`这一层创建一个新的`HeroService`实例。 - 显然,在这个例子中,`HeroDetailComponent`不会希望创建*自己的*服务实例,它想要的就是来自父组件的服务实例。 - 给组件添加一个`providers`数组,就会创建一个新的服务实例,而它会遮蔽父组件中的同名实例。 - - Think carefully about where and when to register a provider. - Understand the scope of that registration. Be careful not to create a new service instance at the wrong level. - - 务必想清楚,在哪里、在什么时候注册供应商。要理解注册的有效范围。小心点!不要在错误的级别上创建新的服务实例。 diff --git a/public/docs/ts/latest/tutorial/toh-pt5.jade b/public/docs/ts/latest/tutorial/toh-pt5.jade index 3ea8a2a58d..62d6a7ff8c 100644 --- a/public/docs/ts/latest/tutorial/toh-pt5.jade +++ b/public/docs/ts/latest/tutorial/toh-pt5.jade @@ -466,9 +466,13 @@ code-example(format="." language="bash"). +makeExample('toh-5/ts/app/dashboard.component.ts', 'template-url', 'app/dashboard.component.ts (templateUrl)')(format=".") .l-sub-section :marked - We specify the path _all the way back to the application root_. Angular doesn't support module-relative paths. + We specify the path _all the way back to the application root_ — `app/` in this case — + because Angular doesn't support relative paths _by default_. + We _can_ switch to [component-relative paths](../cookbook/component-relative-paths) if we prefer. - 我们指定的所有路径都是相对于该应用的根目录的。Angular不支持使用相对于当前模块的路径。 + 我们指定的所有路径_都是相对于该应用的根目录(这里是`app/`)的_。 + 因为Angular_默认_不支持使用相对于当前模块的路径。 + 只要喜欢,我们也_可以_切换成[相对于组件的路径](../cookbook/component-relative-paths)模式。 :marked Create that file with these contents: