diff --git a/public/_includes/_scripts-include.jade b/public/_includes/_scripts-include.jade index 937b923242..aee83952ab 100644 --- a/public/_includes/_scripts-include.jade +++ b/public/_includes/_scripts-include.jade @@ -36,5 +36,4 @@ script(src="/resources/js/directives/code-pane.js") script(src="/resources/js/directives/code-example.js") script(src="/resources/js/directives/if-docs.js") script(src="/resources/js/directives/live-example.js") -script(src="/resources/js/directives/ngio-ex-path.js") -script(src="/resources/js/directives/scroll-y-offset-element.js") \ No newline at end of file +script(src="/resources/js/directives/scroll-y-offset-element.js") diff --git a/public/docs/ts/latest/cookbook/aot-compiler.jade b/public/docs/ts/latest/cookbook/aot-compiler.jade index 9b8128b840..b11519bc8b 100644 --- a/public/docs/ts/latest/cookbook/aot-compiler.jade +++ b/public/docs/ts/latest/cookbook/aot-compiler.jade @@ -283,9 +283,9 @@ a#rollup-plugins Luckily, there is a Rollup plugin that modifies _RxJs_ to use the ES `import` and `export` statements that Rollup requires. - Rollup then preserves the parts of `RxJS` referenced by the application - in the final bundle. Using it is straigthforward. Add the following to - the `plugins` !{_array} in `rollup-config.js`: + Rollup then preserves the parts of `RxJS` referenced by the application + in the final bundle. Using it is straigthforward. Add the following to + the `plugins` array in `rollup-config.js`: +makeExample('cb-aot-compiler/ts/rollup-config.js','commonjs','rollup-config.js (CommonJs to ES2015 Plugin)')(format='.') @@ -293,8 +293,8 @@ a#rollup-plugins *Minification* Rollup tree shaking reduces code size considerably. Minification makes it smaller still. - This cookbook relies on the _uglify_ Rollup plugin to minify and mangle the code. - Add the following to the `plugins` !{_array}: + This cookbook relies on the _uglify_ Rollup plugin to minify and mangle the code. + Add the following to the `plugins` array: +makeExample('cb-aot-compiler/ts/rollup-config.js','uglify','rollup-config.js (CommonJs to ES2015 Plugin)')(format='.') diff --git a/public/docs/ts/latest/glossary.jade b/public/docs/ts/latest/glossary.jade index c2e0683799..f2fc88d1e0 100644 --- a/public/docs/ts/latest/glossary.jade +++ b/public/docs/ts/latest/glossary.jade @@ -1,13 +1,6 @@ block includes include _util-fns -//- current.path = ['docs', lang, 'latest', ...] -- var lang = current.path[1] -- var docsPath='/' + current.path[0] -- var docsLatest='/' + current.path.slice(0,3).join('/'); -- var _at = lang === 'js' ? '' : '@' -- var _decoratorLink = '' + _decorator + '' - :marked Angular has its own vocabulary. Most Angular terms are common English words @@ -29,22 +22,21 @@ a#aot .l-sub-section :marked You can compile Angular applications at build time. - By compiling your application using the compiler-cli, `ngc`, you can bootstrap directly - to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle. + By compiling your application using the compiler-cli, `ngc`, you can bootstrap directly + to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle. Ahead-of-time compiled applications also benefit from decreased load time and increased performance. -+ifDocsFor('ts') +:marked + ## Angular module +.l-sub-section :marked - ## Angular module - .l-sub-section - :marked - Helps you organize an application into cohesive blocks of functionality. - An Angular module identifies the components, directives, and pipes that the application uses along with the list of external Angular modules that the application needs, such as `FormsModule`. + Helps you organize an application into cohesive blocks of functionality. + An Angular module identifies the components, directives, and pipes that the application uses along with the list of external Angular modules that the application needs, such as `FormsModule`. - Every Angular application has an application root-module class. By convention, the class is - called `AppModule` and resides in a file named `app.module.ts`. + Every Angular application has an application root-module class. By convention, the class is + called `AppModule` and resides in a file named `app.module.ts`. - For details and examples, see the [Angular Modules (NgModule)](!{docsLatest}/guide/ngmodule.html) page. + For details and examples, see the [Angular Modules (NgModule)](./ngmodule.html) page. :marked ## Annotation @@ -64,50 +56,49 @@ a#attribute-directives For example, you can use the `ngClass` directive to add and remove CSS class names. - Learn about them in the [_Attribute Directives_](!{docsLatest}/guide/attribute-directives.html) guide. + Learn about them in the [_Attribute Directives_](./attribute-directives.html) guide. .l-main-section#B -+ifDocsFor('ts|js') +:marked + ## Barrel +.l-sub-section :marked - ## Barrel - .l-sub-section - :marked - A way to *roll up exports* from several ES2015 modules into a single convenient ES2015 module. - The barrel itself is an ES2015 module file that re-exports *selected* exports of other ES2015 modules. + A way to *roll up exports* from several ES2015 modules into a single convenient ES2015 module. + The barrel itself is an ES2015 module file that re-exports *selected* exports of other ES2015 modules. - For example, imagine three ES2015 modules in a `heroes` folder: - code-example. - // heroes/hero.component.ts - export class HeroComponent {} + For example, imagine three ES2015 modules in a `heroes` folder: + code-example. + // heroes/hero.component.ts + export class HeroComponent {} - // heroes/hero.model.ts - export class Hero {} + // heroes/hero.model.ts + export class Hero {} - // heroes/hero.service.ts - export class HeroService {} - :marked - Without a barrel, a consumer needs three import statements: - code-example. - import { HeroComponent } from '../heroes/hero.component.ts'; - import { Hero } from '../heroes/hero.model.ts'; - import { HeroService } from '../heroes/hero.service.ts'; - :marked - You can add a barrel to the `heroes` folder (called `index`, by convention) that exports all of these items: - code-example. - export * from './hero.model.ts'; // re-export all of its exports - export * from './hero.service.ts'; // re-export all of its exports - export { HeroComponent } from './hero.component.ts'; // re-export the named thing - :marked - Now a consumer can import what it needs from the barrel. - code-example. - import { Hero, HeroService } from '../heroes'; // index is implied - :marked - The Angular [scoped packages](#scoped-package) each have a barrel named `index`. + // heroes/hero.service.ts + export class HeroService {} + :marked + Without a barrel, a consumer needs three import statements: + code-example. + import { HeroComponent } from '../heroes/hero.component.ts'; + import { Hero } from '../heroes/hero.model.ts'; + import { HeroService } from '../heroes/hero.service.ts'; + :marked + You can add a barrel to the `heroes` folder (called `index`, by convention) that exports all of these items: + code-example. + export * from './hero.model.ts'; // re-export all of its exports + export * from './hero.service.ts'; // re-export all of its exports + export { HeroComponent } from './hero.component.ts'; // re-export the named thing + :marked + Now a consumer can import what it needs from the barrel. + code-example. + import { Hero, HeroService } from '../heroes'; // index is implied + :marked + The Angular [scoped packages](#scoped-package) each have a barrel named `index`. - .alert.is-important - :marked - You can often achieve the same result using [Angular modules](#angular-module) instead. + .alert.is-important + :marked + You can often achieve the same result using [Angular modules](#angular-module) instead. :marked ## Binding @@ -126,7 +117,7 @@ a#attribute-directives You launch an Angular application by "bootstrapping" it using the application root Angular module (`AppModule`). Bootstrapping identifies an application's top level "root" [component](#component), which is the first component that is loaded for the application. - For more information, see the [Setup](!{docsLatest}/guide/setup.html) page. + For more information, see the [Setup](./setup.html) page. You can bootstrap multiple apps in the same `index.html`, each app with its own top-level root. @@ -153,7 +144,7 @@ a#component The *component* is one of the most important building blocks in the Angular system. It is, in fact, an Angular [directive](#directive) with a companion [template](#template). - Apply the `!{_at}Component` !{_decoratorLink} to + Apply the `@Component` [decorator](#decorator) to the component class, thereby attaching to the class the essential component metadata that Angular needs to create a component instance and render the component with its template as a view. @@ -169,8 +160,8 @@ a#component The practice of writing compound words or phrases such that each word is separated by a dash or hyphen (`-`). This form is also known as kebab-case. - [Directive](#directive) selectors (like `my-app`) and - the root of filenames (such as `hero-list.component.ts`) are often + [Directive](#directive) selectors (like `my-app`) and + the root of filenames (such as `hero-list.component.ts`) are often spelled in dash-case. :marked @@ -189,14 +180,14 @@ a#component Angular has a rich data-binding framework with a variety of data-binding operations and supporting declaration syntax. - Read about the following forms of binding in the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page: - * [Interpolation](!{docsLatest}/guide/template-syntax.html#interpolation). - * [Property binding](!{docsLatest}/guide/template-syntax.html#property-binding). - * [Event binding](!{docsLatest}/guide/template-syntax.html#event-binding). - * [Attribute binding](!{docsLatest}/guide/template-syntax.html#attribute-binding). - * [Class binding](!{docsLatest}/guide/template-syntax.html#class-binding). - * [Style binding](!{docsLatest}/guide/template-syntax.html#style-binding). - * [Two-way data binding with ngModel](!{docsLatest}/guide/template-syntax.html#ngModel). + Read about the following forms of binding in the [Template Syntax](./template-syntax.html) page: + * [Interpolation](./template-syntax.html#interpolation). + * [Property binding](./template-syntax.html#property-binding). + * [Event binding](./template-syntax.html#event-binding). + * [Attribute binding](./template-syntax.html#attribute-binding). + * [Class binding](./template-syntax.html#class-binding). + * [Style binding](./template-syntax.html#style-binding). + * [Two-way data binding with ngModel](./template-syntax.html#ngModel). a#decorator a#decoration @@ -280,7 +271,7 @@ a#decoration Angular registers some of its own providers with every injector. You can register your own providers. - Read more in the [Dependency Injection](!{docsLatest}/guide/dependency-injection.html) page. + Read more in the [Dependency Injection](./dependency-injection.html) page. a#directive a#directives @@ -370,11 +361,11 @@ a#H .l-sub-section :marked A directive property that can be the *target* of a - [property binding](!{docsLatest}/guide/template-syntax.html#property-binding) (explained in detail in the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page). + [property binding](./template-syntax.html#property-binding) (explained in detail in the [Template Syntax](./template-syntax.html) page). Data values flow *into* this property from the data source identified in the template expression to the right of the equal sign. - See the [Input and output properties](!{docsLatest}/guide/template-syntax.html#inputs-outputs) section of the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page. + See the [Input and output properties](./template-syntax.html#inputs-outputs) section of the [Template Syntax](./template-syntax.html) page. :marked ## Interpolation @@ -390,8 +381,8 @@ a#H :marked - Read more about [interpolation](!{docsLatest}/guide/template-syntax.html#interpolation) in the - [Template Syntax](!{docsLatest}/guide/template-syntax.html) page. + Read more about [interpolation](./template-syntax.html#interpolation) in the + [Template Syntax](./template-syntax.html) page. .l-main-section#J @@ -400,7 +391,7 @@ a#jit ## Just-in-time (JIT) compilation .l-sub-section :marked - A bootstrapping method of compiling components and modules in the browser + A bootstrapping method of compiling components and modules in the browser and launching the application dynamically. Just-in-time mode is a good choice during development. Consider using the [ahead-of-time](#aot) mode for production apps. @@ -435,7 +426,7 @@ a#jit * `ngAfterViewChecked`: after every check of a component's views. * `ngOnDestroy`: just before the directive is destroyed. - Read more in the [Lifecycle Hooks](!{docsLatest}/guide/lifecycle-hooks.html) page. + Read more in the [Lifecycle Hooks](./lifecycle-hooks.html) page. .l-main-section#M @@ -446,7 +437,7 @@ a#jit :marked Angular has the following types of modules: - [Angular modules](#angular-module). - For details and examples, see the [Angular Modules](!{docsLatest}/guide/ngmodule.html) page. + For details and examples, see the [Angular Modules](./ngmodule.html) page. - ES2015 modules, as described in this section. :marked @@ -477,29 +468,28 @@ a#jit a#N .l-main-section#O -+ifDocsFor('ts|js') +:marked + ## Observable +.l-sub-section :marked - ## Observable - .l-sub-section - :marked - An array whose items arrive asynchronously over time. - Observables help you manage asynchronous data, such as data coming from a backend service. - Observables are used within Angular itself, including Angular's event system and its HTTP client service. + An array whose items arrive asynchronously over time. + Observables help you manage asynchronous data, such as data coming from a backend service. + Observables are used within Angular itself, including Angular's event system and its HTTP client service. - To use observables, Angular uses a third-party library called Reactive Extensions (RxJS). - Observables are a proposed feature for ES2016, the next version of JavaScript. + To use observables, Angular uses a third-party library called Reactive Extensions (RxJS). + Observables are a proposed feature for ES2016, the next version of JavaScript. :marked ## Output .l-sub-section :marked A directive property that can be the *target* of event binding - (read more in the [event binding](!{docsLatest}/guide/template-syntax.html#event-binding) - section of the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page). + (read more in the [event binding](./template-syntax.html#event-binding) + section of the [Template Syntax](./template-syntax.html) page). Events stream *out* of this property to the receiver identified in the template expression to the right of the equal sign. - See the [Input and output properties](!{docsLatest}/guide/template-syntax.html#inputs-outputs) section of the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page. + See the [Input and output properties](./template-syntax.html#inputs-outputs) section of the [Template Syntax](./template-syntax.html) page. .l-main-section#P @@ -527,7 +517,7 @@ a#N :marked You can also write your own custom pipes. - Read more in the page on [pipes](!{docsLatest}/guide/pipes.html). + Read more in the page on [pipes](./pipes.html). :marked ## Provider @@ -566,18 +556,17 @@ a#Q The Angular component router is a richly featured mechanism for configuring and managing the entire view navigation process, including the creation and destruction of views. - +ifDocsFor('ts|js') - :marked - In most cases, components become attached to a router by means - of a `RouterConfig` that defines routes to views. + + In most cases, components become attached to a router by means + of a `RouterConfig` that defines routes to views. - A [routing component's](#routing-component) template has a `RouterOutlet` element - where it can display views produced by the router. + A [routing component's](#routing-component) template has a `RouterOutlet` element + where it can display views produced by the router. - Other views in the application likely have anchor tags or buttons with `RouterLink` - directives that users can click to navigate. + Other views in the application likely have anchor tags or buttons with `RouterLink` + directives that users can click to navigate. - For more information, see the [Routing & Navigation](!{docsLatest}/guide/router.html) page. + For more information, see the [Routing & Navigation](./router.html) page. :marked ## Router module @@ -585,7 +574,7 @@ a#Q :marked A separate [Angular module](#angular-module) that provides the necessary service providers and directives for navigating through application views. - For more information, see the [Routing & Navigation](!{docsLatest}/guide/router.html) page. + For more information, see the [Routing & Navigation](./router.html) page. :marked ## Routing component @@ -593,7 +582,7 @@ a#Q :marked An Angular [component](#component) with a `RouterOutlet` that displays views based on router navigations. - For more information, see the [Routing & Navigation](!{docsLatest}/guide/router.html) page. + For more information, see the [Routing & Navigation](./router.html) page. .l-main-section#S @@ -629,7 +618,7 @@ a#Q Applications often require services such as a data service or a logging service. - For more information, see the [Services](!{docsLatest}/tutorial/toh-pt4.html) page of the [Tour of Heroes](!{docsLatest}/tutorial/) tutorial. + For more information, see the [Services](.ial/toh-pt4.html) page of the [Tour of Heroes](.ial/) tutorial. a#snake-case :marked @@ -650,7 +639,7 @@ a#structural-directives shape or reshape HTML layout, typically by adding and removing elements in the DOM. The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive are well-known examples. - Read more in the [Structural Directives](!{docsLatest}/guide/structural-directives.html) page. + Read more in the [Structural Directives](./structural-directives.html) page. .l-main-section#T :marked @@ -677,18 +666,18 @@ a#structural-directives Template-driven forms are convenient, quick, and simple. They are a good choice for many basic data-entry form scenarios. Read about how to build template-driven forms - in the [Forms](!{docsLatest}/guide/forms.html) page. + in the [Forms](./forms.html) page. :marked ## Template expression .l-sub-section :marked - A !{_Lang}-like syntax that Angular evaluates within + A TypeScript-like syntax that Angular evaluates within a [data binding](#data-binding). Read about how to write template expressions - in the [Template expressions](!{docsLatest}/guide/template-syntax.html#template-expressions) section - of the [Template Syntax](!{docsLatest}/guide/template-syntax.html#) page. + in the [Template expressions](./template-syntax.html#template-expressions) section + of the [Template Syntax](./template-syntax.html#) page. :marked ## Transpile diff --git a/public/docs/ts/latest/guide/animations.jade b/public/docs/ts/latest/guide/animations.jade index 2077bf87b6..05e7fcec18 100644 --- a/public/docs/ts/latest/guide/animations.jade +++ b/public/docs/ts/latest/guide/animations.jade @@ -172,7 +172,7 @@ figure * Enter: `void => *` * Leave: `* => void` - For example, in the `animations` !{_array} below there are two transitions that use + For example, in the `animations` array below there are two transitions that use the `void => *` and `* => void` syntax to animate the element in and out of the view. +makeExample('animations/ts/src/app/hero-list-enter-leave.component.ts', 'animationdef', 'hero-list-enter-leave.component.ts (excerpt)')(format=".") diff --git a/public/docs/ts/latest/guide/architecture.jade b/public/docs/ts/latest/guide/architecture.jade index 00b8c324d1..a03d9f5503 100644 --- a/public/docs/ts/latest/guide/architecture.jade +++ b/public/docs/ts/latest/guide/architecture.jade @@ -1,14 +1,11 @@ block includes include ../_util-fns - - var _library_module = 'library module' - - var _at_angular = '@angular' -block angular-intro - :marked - Angular is a framework for building client applications in HTML and - either JavaScript or a language like TypeScript that compiles to JavaScript. +:marked + Angular is a framework for building client applications in HTML and + either JavaScript or a language like TypeScript that compiles to JavaScript. - The framework consists of several libraries, some of them core and some optional. + The framework consists of several libraries, some of them core and some optional. :marked You write Angular applications by composing HTML *templates* with Angularized markup, @@ -48,78 +45,77 @@ figure figure img(src="/resources/images/devguide/architecture/module.png" alt="Component" align="left" style="width:240px; margin-left:-40px;margin-right:10px" ) -block angular-modules +:marked + Angular apps are modular and Angular has its own modularity system called _Angular modules_ or _NgModules_. + + _Angular modules_ are a big deal. + This page introduces modules; the [Angular modules](ngmodule.html) page covers them in depth. + +

+:marked + Every Angular app has at least one Angular module class, [the _root module_](appmodule.html "AppModule: the root module"), + conventionally named `AppModule`. + + While the _root module_ may be the only module in a small application, most apps have many more + _feature modules_, each a cohesive block of code dedicated to an application domain, + a workflow, or a closely related set of capabilities. + + An Angular module, whether a _root_ or _feature_, is a class with an `@NgModule` decorator. +.l-sub-section :marked - Angular apps are modular and Angular has its own modularity system called _Angular modules_ or _NgModules_. + Decorators are functions that modify JavaScript classes. + Angular has many decorators that attach metadata to classes so that it knows + what those classes mean and how they should work. + + Learn more about decorators on the web. +:marked + `NgModule` is a decorator function that takes a single metadata object whose properties describe the module. + The most important properties are: + * `declarations` - the _view classes_ that belong to this module. + Angular has three kinds of view classes: [components](#components), [directives](#directives), and [pipes](pipes.html). - _Angular modules_ are a big deal. - This page introduces modules; the [Angular modules](ngmodule.html) page covers them in depth. + * `exports` - the subset of declarations that should be visible and usable in the component [templates](#templates) of other modules. -

+ * `imports` - other modules whose exported classes are needed by component templates declared in _this_ module. + + * `providers` - creators of [services](#services) that this module contributes to + the global collection of services; they become accessible in all parts of the app. + + * `bootstrap` - the main application view, called the _root component_, + that hosts all other app views. Only the _root module_ should set this `bootstrap` property. + + Here's a simple root module: ++makeExample('src/app/mini-app.ts', 'module', 'src/app/app.module.ts')(format='.') + +.l-sub-section :marked - Every Angular app has at least one Angular module class, [the _root module_](appmodule.html "AppModule: the root module"), - conventionally named `AppModule`. - - While the _root module_ may be the only module in a small application, most apps have many more - _feature modules_, each a cohesive block of code dedicated to an application domain, - a workflow, or a closely related set of capabilities. - - An Angular module, whether a _root_ or _feature_, is a class with an `@NgModule` decorator. - .l-sub-section - :marked - Decorators are functions that modify JavaScript classes. - Angular has many decorators that attach metadata to classes so that it knows - what those classes mean and how they should work. - - Learn more about decorators on the web. - :marked - `NgModule` is a decorator function that takes a single metadata object whose properties describe the module. - The most important properties are: - * `declarations` - the _view classes_ that belong to this module. - Angular has three kinds of view classes: [components](#components), [directives](#directives), and [pipes](pipes.html). - - * `exports` - the subset of declarations that should be visible and usable in the component [templates](#templates) of other modules. - - * `imports` - other modules whose exported classes are needed by component templates declared in _this_ module. - - * `providers` - creators of [services](#services) that this module contributes to - the global collection of services; they become accessible in all parts of the app. - - * `bootstrap` - the main application view, called the _root component_, - that hosts all other app views. Only the _root module_ should set this `bootstrap` property. - - Here's a simple root module: - +makeExample('src/app/mini-app.ts', 'module', 'src/app/app.module.ts')(format='.') - - .l-sub-section - :marked - The `export` of `AppComponent` is just to show how to export; it isn't actually necessary in this example. A root module has no reason to _export_ anything because other components don't need to _import_ the root module. - :marked - Launch an application by _bootstrapping_ its root module. - During development you're likely to bootstrap the `AppModule` in a `main.ts` file like this one. - - +makeExample('src/main.ts', '', 'src/main.ts')(format='.') - - :marked - ### Angular modules vs. JavaScript modules - - The Angular module — a class decorated with `@NgModule` — is a fundamental feature of Angular. - - JavaScript also has its own module system for managing collections of JavaScript objects. - It's completely different and unrelated to the Angular module system. + The `export` of `AppComponent` is just to show how to export; it isn't actually necessary in this example. A root module has no reason to _export_ anything because other components don't need to _import_ the root module. +:marked + Launch an application by _bootstrapping_ its root module. + During development you're likely to bootstrap the `AppModule` in a `main.ts` file like this one. - In JavaScript each _file_ is a module and all objects defined in the file belong to that module. - The module declares some objects to be public by marking them with the `export` key word. - Other JavaScript modules use *import statements* to access public objects from other modules. ++makeExample('src/main.ts', '', 'src/main.ts')(format='.') - +makeExample('src/app/app.module.ts', 'imports', '')(format='.') - +makeExample('src/app/app.module.ts', 'export', '')(format='.') - - .l-sub-section - :marked - Learn more about the JavaScript module system on the web. +:marked + ### Angular modules vs. JavaScript modules + + The Angular module — a class decorated with `@NgModule` — is a fundamental feature of Angular. + + JavaScript also has its own module system for managing collections of JavaScript objects. + It's completely different and unrelated to the Angular module system. + + In JavaScript each _file_ is a module and all objects defined in the file belong to that module. + The module declares some objects to be public by marking them with the `export` key word. + Other JavaScript modules use *import statements* to access public objects from other modules. + ++makeExample('src/app/app.module.ts', 'imports', '')(format='.') ++makeExample('src/app/app.module.ts', 'export', '')(format='.') + +.l-sub-section :marked - These are two different and _complementary_ module systems. Use them both to write your apps. + Learn more about the JavaScript module system on the web. +:marked + These are two different and _complementary_ module systems. Use them both to write your apps. :marked ### Angular libraries @@ -127,32 +123,31 @@ block angular-modules figure img(src="/resources/images/devguide/architecture/library-module.png" alt="Component" align="left" style="width:240px; margin-left:-40px;margin-right:10px" ) -block angular-libraries - :marked - Angular ships as a collection of JavaScript modules. You can think of them as library modules. +:marked + Angular ships as a collection of JavaScript modules. You can think of them as library modules. - Each Angular library name begins with the `!{_at_angular}` prefix. - - You install them with the **npm** package manager and import parts of them with JavaScript `import` statements. -

+ Each Angular library name begins with the `@angular` prefix. + + You install them with the **npm** package manager and import parts of them with JavaScript `import` statements. +

- For example, import Angular's `Component` decorator from the `@angular/core` library like this: - +makeExample('src/app/app.component.ts', 'import', '')(format='.') - :marked - You also import Angular _modules_ from Angular _libraries_ using JavaScript import statements: - +makeExample('src/app/mini-app.ts', 'import-browser-module', '')(format='.') - :marked - In the example of the simple root module above, the application module needs material from within that `BrowserModule`. To access that material, add it to the `@NgModule` metadata `imports` like this. - +makeExample('src/app/mini-app.ts', 'ngmodule-imports', '')(format='.') - :marked - In this way you're using both the Angular and JavaScript module systems _together_. + For example, import Angular's `Component` decorator from the `@angular/core` library like this: ++makeExample('src/app/app.component.ts', 'import', '')(format='.') +:marked + You also import Angular _modules_ from Angular _libraries_ using JavaScript import statements: ++makeExample('src/app/mini-app.ts', 'import-browser-module', '')(format='.') +:marked + In the example of the simple root module above, the application module needs material from within that `BrowserModule`. To access that material, add it to the `@NgModule` metadata `imports` like this. ++makeExample('src/app/mini-app.ts', 'ngmodule-imports', '')(format='.') +:marked + In this way you're using both the Angular and JavaScript module systems _together_. - It's easy to confuse the two systems because they share the common vocabulary of "imports" and "exports". - Hang in there. The confusion yields to clarity with time and experience. + It's easy to confuse the two systems because they share the common vocabulary of "imports" and "exports". + Hang in there. The confusion yields to clarity with time and experience. - .l-sub-section - :marked - Learn more from the [Angular modules](ngmodule.html) page. +.l-sub-section + :marked + Learn more from the [Angular modules](ngmodule.html) page. .l-hr @@ -176,7 +171,7 @@ figure The class interacts with the view through an API of properties and methods. - For example, this `HeroListComponent` has a `heroes` property that returns !{_an} !{_array} of heroes + For example, this `HeroListComponent` has a `heroes` property that returns an array of heroes that it acquires from a service. `HeroListComponent` also has a `selectHero()` method that sets a `selectedHero` property when the user clicks to choose a hero from that list. @@ -238,21 +233,20 @@ figure To tell Angular that `HeroListComponent` is a component, attach **metadata** to the class. - In !{_Lang}, you attach metadata by using !{_a} **!{_decorator}**. + In TypeScript, you attach metadata by using a **decorator**. Here's some metadata for `HeroListComponent`: +makeExcerpt('src/app/hero-list.component.ts', 'metadata') :marked - Here is the `@Component` !{_decorator}, which identifies the class + Here is the `@Component` decorator, which identifies the class immediately below it as a component class. -block ts-decorator - :marked - The `@Component` decorator takes a required configuration object with the - information Angular needs to create and present the component and its view. +:marked + The `@Component` decorator takes a required configuration object with the + information Angular needs to create and present the component and its view. - Here are a few of the most useful `@Component` configuration options: + Here are a few of the most useful `@Component` configuration options: :marked - `selector`: CSS selector that tells Angular to create and insert an instance of this component @@ -262,10 +256,8 @@ block ts-decorator - `templateUrl`: module-relative address of this component's HTML template, shown [above](#templates). -block dart-directives - :marked - - `providers`: !{_array} of **dependency injection providers** for services that the component requires. + - `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. @@ -277,8 +269,8 @@ figure The template, metadata, and component together describe a view. - Apply other metadata !{_decorator}s in a similar fashion to guide Angular behavior. - `@Injectable`, `@Input`, and `@Output` are a few of the more popular !{_decorator}s. + Apply other metadata decorators in a similar fashion to guide Angular behavior. + `@Injectable`, `@Input`, and `@Output` are a few of the more popular decorators.
:marked The architectural takeaway is that you must add metadata to your code @@ -352,9 +344,9 @@ figure Angular templates are *dynamic*. When Angular renders them, it transforms the DOM according to the instructions given by **directives**. - A directive is a class with a `@Directive` !{_decorator}. + A directive is a class with a `@Directive` decorator. A component is a *directive-with-a-template*; - a `@Component` !{_decorator} is actually a `@Directive` !{_decorator} extended with template-oriented features. + a `@Component` decorator is actually a `@Directive` decorator extended with template-oriented features.
.l-sub-section @@ -377,8 +369,6 @@ figure * [`*ngFor`](displaying-data.html#ngFor) tells Angular to stamp out one `
  • ` per hero in the `heroes` list. * [`*ngIf`](displaying-data.html#ngIf) includes the `HeroDetail` component only if a selected hero exists. -block dart-bool - :marked **Attribute** directives alter the appearance or behavior of an existing element. In templates they look like regular HTML attributes, hence the name. @@ -430,7 +420,7 @@ figure +makeExcerpt('src/app/logger.service.ts', 'class') :marked - Here's a `HeroService` that uses a !{_PromiseLinked} to fetch heroes. + Here's a `HeroService` that uses a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to fetch heroes. The `HeroService` depends on the `Logger` service and another `BackendService` that handles the server communication grunt work. +makeExcerpt('src/app/hero.service.ts', 'class') @@ -491,14 +481,13 @@ figure In brief, you must have previously registered a **provider** of the `HeroService` with the injector. A provider is something that can create or return a service, typically the service class itself. -block registering-providers - :marked - You can register providers in modules or in components. - - In general, add providers to the [root module](#module) so that - the same instance of a service is available everywhere. +:marked + You can register providers in modules or in components. + + In general, add providers to the [root module](#module) so that + the same instance of a service is available everywhere. - +makeExcerpt('src/app/app.module.ts (module providers)', 'providers') ++makeExcerpt('src/app/app.module.ts (module providers)', 'providers') :marked Alternatively, register at a component level in the `providers` property of the `@Component` metadata: @@ -573,7 +562,6 @@ block registering-providers > [**Router**](router.html): Navigate from page to page within the client application and never leave the browser. -block angular-feature-testing - :marked - > [**Testing**](testing.html): Run unit tests on your application parts as they interact with the Angular framework - using the _Angular Testing Platform_. +:marked + > [**Testing**](testing.html): Run unit tests on your application parts as they interact with the Angular framework + using the _Angular Testing Platform_. diff --git a/public/docs/ts/latest/guide/attribute-directives.jade b/public/docs/ts/latest/guide/attribute-directives.jade index dee09df5af..385d0d616a 100644 --- a/public/docs/ts/latest/guide/attribute-directives.jade +++ b/public/docs/ts/latest/guide/attribute-directives.jade @@ -56,7 +56,7 @@ block includes ### Write the directive code Follow the [setup](setup.html) instructions for creating a new local project - named attribute-directives. + named attribute-directives. Create the following source file in the indicated folder: @@ -97,7 +97,7 @@ block includes :marked After the `@Directive` metadata comes the directive's controller class, called `HighlightDirective`, which contains the logic for the directive. - Exporting `HighlightDirective` makes it accessible to other components. + Exporting `HighlightDirective` makes it accessible to other components. Angular creates a new instance of the directive's controller class for each matching element, injecting an Angular `ElementRef` @@ -113,7 +113,7 @@ block includes applies the directive as an attribute to a paragraph (`

    `) element. In Angular terms, the `

    ` element is the attribute **host**. - Put the template in its own app.component.html + Put the template in its own app.component.html file that looks like this: +makeExample('src/app/app.component.1.html') @@ -176,12 +176,12 @@ figure.image-display :marked Then add two eventhandlers that respond when the mouse enters or leaves, - each adorned by the `HostListener` !{_decorator}. + each adorned by the `HostListener` decorator. +makeExcerpt('src/app/highlight.directive.2.ts','mouse-methods', '') :marked - The `@HostListener` !{_decorator} lets you subscribe to events of the DOM + The `@HostListener` decorator lets you subscribe to events of the DOM element that hosts an attribute directive, the `

    ` in this case. .l-sub-section @@ -194,7 +194,7 @@ figure.image-display 1. Talking to DOM API directly isn't a best practice. :marked - The handlers delegate to a helper method that sets the color on the DOM element, `#{_priv}el`, + The handlers delegate to a helper method that sets the color on the DOM element, `el`, which you declare and initialize in the constructor. +makeExcerpt('src/app/highlight.directive.2.ts (constructor)', 'ctor') @@ -226,7 +226,7 @@ a#input :marked ### Binding to an _@Input_ property - Notice the `@Input` !{_decorator}. It adds metadata to the class that makes the directive's `highlightColor` property available for binding. + Notice the `@Input` decorator. It adds metadata to the class that makes the directive's `highlightColor` property available for binding. It's called an *input* property because data flows from the binding expression _into_ the directive. Without that input metadata, Angular rejects the binding; see [below](#why-input "Why add @Input?") for more about that. @@ -299,7 +299,7 @@ a#input-alias In this section, you'll turn `AppComponent` into a harness that lets you pick the highlight color with a radio button and bind your color choice to the directive. - Update app.component.html as follows: + Update app.component.html as follows: +makeExcerpt('src/app/app.component.html', 'v2', '') @@ -345,7 +345,7 @@ figure.image-display :marked Angular knows that the `defaultColor` binding belongs to the `HighlightDirective` - because you made it _public_ with the `@Input` !{_decorator}. + because you made it _public_ with the `@Input` decorator. Here's how the harness should work when you're done coding. @@ -400,7 +400,7 @@ figure.image-display +makeExcerpt('src/app/highlight.directive.ts', 'color', '') :marked - Either way, the `@Input` !{_decorator} tells Angular that this property is + Either way, the `@Input` decorator tells Angular that this property is _public_ and available for binding by a parent component. Without `@Input`, Angular refuses to bind to the property. @@ -411,22 +411,22 @@ figure.image-display Angular treats a component's template as _belonging_ to the component. The component and its template trust each other implicitly. Therefore, the component's own template may bind to _any_ property of that component, - with or without the `@Input` !{_decorator}. + with or without the `@Input` decorator. But a component or directive shouldn't blindly trust _other_ components and directives. The properties of a component or directive are hidden from binding by default. They are _private_ from an Angular binding perspective. - When adorned with the `@Input` !{_decorator}, the property becomes _public_ from an Angular binding perspective. + When adorned with the `@Input` decorator, the property becomes _public_ from an Angular binding perspective. Only then can it be bound by some other component or directive. You can tell if `@Input` is needed by the position of the property name in a binding. * When it appears in the template expression to the ***right*** of the equals (=), - it belongs to the template's component and does not require the `@Input` !{_decorator}. + it belongs to the template's component and does not require the `@Input` decorator. * When it appears in **square brackets** ([ ]) to the **left** of the equals (=), the property belongs to some _other_ component or directive; - that property must be adorned with the `@Input` !{_decorator}. + that property must be adorned with the `@Input` decorator. Now apply that reasoning to the following example: @@ -435,8 +435,8 @@ figure.image-display :marked * The `color` property in the expression on the right belongs to the template's component. The template and its component trust each other. - The `color` property doesn't require the `@Input` !{_decorator}. + The `color` property doesn't require the `@Input` decorator. * The `myHighlight` property on the left refers to an _aliased_ property of the `HighlightDirective`, not a property of the template's component. There are trust issues. - Therefore, the directive property must carry the `@Input` !{_decorator}. + Therefore, the directive property must carry the `@Input` decorator. diff --git a/public/docs/ts/latest/guide/browser-support.jade b/public/docs/ts/latest/guide/browser-support.jade index 55204994af..0cd1d8b52a 100644 --- a/public/docs/ts/latest/guide/browser-support.jade +++ b/public/docs/ts/latest/guide/browser-support.jade @@ -1,6 +1,5 @@ block includes include ../_util-fns - - var _at_angular = '@angular' :marked Angular supports most recent browsers. This includes the following specific versions: diff --git a/public/docs/ts/latest/guide/component-styles.jade b/public/docs/ts/latest/guide/component-styles.jade index bf608ae90e..e1aea3c1dc 100644 --- a/public/docs/ts/latest/guide/component-styles.jade +++ b/public/docs/ts/latest/guide/component-styles.jade @@ -31,7 +31,7 @@ block includes specifying any selectors, rules, and media queries that you need. One way to do this is to set the `styles` property in the component metadata. - The `styles` property takes #{_an} #{_array} of strings that contain CSS code. + The `styles` property takes an array of strings that contain CSS code. Usually you give it one string, as in the following example: +makeExample('component-styles/ts/src/app/hero-app.component.ts')(format='.') @@ -134,8 +134,8 @@ a(id='loading-styles') ### Styles in metadata - You can add a `styles` #{_array} property to the `@Component` #{_decorator}. - Each string in the #{_array} (usually just one string) defines the CSS. + You can add a `styles` array property to the `@Component` decorator. + Each string in the array (usually just one string) defines the CSS. +makeExample('component-styles/ts/src/app/hero-app.component.ts') @@ -143,32 +143,30 @@ a(id='loading-styles') ### Style URLs in metadata You can load styles from external CSS files by adding a `styleUrls` attribute - into a component's `@Component` #{_decorator}: + into a component's `@Component` decorator: +makeExample('component-styles/ts/src/app/hero-details.component.ts', 'styleurls') -block style-url - .alert.is-important - :marked - The URL is relative to the *application root*, which is usually the - location of the `index.html` web page that hosts the application. - The style file URL is *not* relative to the component file. - That's why the example URL begins `src/app/`. - To specify a URL relative to the component file, see [Appendix 2](#relative-urls). +.alert.is-important + :marked + The URL is relative to the *application root*, which is usually the + location of the `index.html` web page that hosts the application. + The style file URL is *not* relative to the component file. + That's why the example URL begins `src/app/`. + To specify a URL relative to the component file, see [Appendix 2](#relative-urls). -block module-bundlers - .l-sub-section - :marked - If you use module bundlers like Webpack, you can also use the `styles` attribute - to load styles from external files at build time. You could write: +.l-sub-section + :marked + If you use module bundlers like Webpack, you can also use the `styles` attribute + to load styles from external files at build time. You could write: - `styles: [require('my.component.css')]` + `styles: [require('my.component.css')]` - Set the `styles` property, not the `styleUrls` property. The module - bundler loads the CSS strings, not Angular. - Angular sees the CSS strings only after the bundler loads them. - To Angular, it's as if you wrote the `styles` array by hand. - For information on loading CSS in this manner, refer to the module bundler's documentation. + Set the `styles` property, not the `styleUrls` property. The module + bundler loads the CSS strings, not Angular. + Angular sees the CSS strings only after the bundler loads them. + To Angular, it's as if you wrote the `styles` array by hand. + For information on loading CSS in this manner, refer to the module bundler's documentation. :marked ### Template inline styles @@ -195,9 +193,8 @@ block module-bundlers For details, see [`@import`](https://developer.mozilla.org/en/docs/Web/CSS/@import) on the [MDN](https://developer.mozilla.org) site. -block css-import-url - :marked - In this case, the URL is relative to the CSS file into which you're importing. +:marked + In this case, the URL is relative to the CSS file into which you're importing. +makeExample('component-styles/ts/src/app/hero-details.component.css', 'import', 'src/app/hero-details.component.css (excerpt)') @@ -300,9 +297,8 @@ code-example(format="nocode"). Because these files are co-located with the component, it would be nice to refer to them by name without also having to specify a path back to the root of the application. -block module-id - :marked - You can use a relative URL by prefixing your filenames with `./`: +:marked + You can use a relative URL by prefixing your filenames with `./`: - +makeExample('src/app/quest-summary.component.ts') ++makeExample('src/app/quest-summary.component.ts') diff --git a/public/docs/ts/latest/guide/dependency-injection.jade b/public/docs/ts/latest/guide/dependency-injection.jade index 209b9ea0f9..c203d67263 100644 --- a/public/docs/ts/latest/guide/dependency-injection.jade +++ b/public/docs/ts/latest/guide/dependency-injection.jade @@ -1,6 +1,5 @@ block includes include ../_util-fns - - var _thisDot = 'this.'; :marked **Dependency injection** is an important application design pattern. @@ -62,7 +61,7 @@ block includes What if the `Engine` class evolves and its constructor requires a parameter? That would break the `Car` class and it would stay broken until you rewrote it along the lines of - `#{_thisDot}engine = new Engine(theNewParameter)`. + `this.engine = new Engine(theNewParameter)`. The `Engine` constructor parameters weren't even a consideration when you first wrote `Car`. You may not anticipate them even now. But you'll *have* to start caring because @@ -108,11 +107,10 @@ block includes The `Car` class no longer creates an `engine` or `tires`. It just consumes them. -block ctor-syntax - .l-sub-section - :marked - This example leverages TypeScript's constructor syntax for declaring - parameters and properties simultaneously. +.l-sub-section + :marked + This example leverages TypeScript's constructor syntax for declaring + parameters and properties simultaneously. :marked Now you can create a car by passing the engine and tires to the constructor. @@ -133,8 +131,7 @@ block ctor-syntax The _consumer_ of `Car` has the problem. The consumer must update the car creation code to something like this: - - var stylePattern = { otl: /(new Car.*$)/gm }; - +makeExample('dependency-injection/ts/src/app/car/car-creations.ts', 'car-ctor-instantiation-with-param', '', stylePattern)(format=".") + +makeExample('dependency-injection/ts/src/app/car/car-creations.ts', 'car-ctor-instantiation-with-param', '', { otl: /(new Car.*$)/gm })(format=".") :marked The critical point is this: the `Car` class did not have to change. @@ -146,8 +143,7 @@ block ctor-syntax You can pass mocks to the constructor that do exactly what you want them to do during each test: -- var stylePattern = { otl: /(new Car.*$)/gm }; -+makeExample('dependency-injection/ts/src/app/car/car-creations.ts', 'car-ctor-instantiation-with-mocks', '', stylePattern)(format=".") ++makeExample('dependency-injection/ts/src/app/car/car-creations.ts', 'car-ctor-instantiation-with-mocks', '', { otl: /(new Car.*$)/gm })(format=".") :marked **You just learned what dependency injection is**. @@ -236,9 +232,8 @@ block ctor-syntax Given that the service is a [separate concern](https://en.wikipedia.org/wiki/Separation_of_concerns), consider writing the service code in its own file. - +ifDocsFor('ts') - :marked - See [this note](#one-class-per-file) for details. + + See [this note](#one-class-per-file) for details. :marked The following `HeroService` exposes a `getHeroes` method that returns the same mock data as before, but none of its consumers need to know that. @@ -248,15 +243,14 @@ block ctor-syntax :marked .l-sub-section :marked - The `@Injectable()` #{_decorator} above the service class is + The `@Injectable()` decorator above the service class is covered [shortly](#injectable). -- var _perhaps = _docsFor == 'dart' ? '' : 'perhaps'; .l-sub-section :marked Of course, this isn't a real service. If the app were actually getting data from a remote server, the API would have to be - asynchronous, #{_perhaps} returning a !{_PromiseLinked}. + asynchronous, perhaps returning a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). You'd also have to rewrite the way components consume the service. This is important in general, but not in this example. @@ -279,18 +273,16 @@ a#injector-config that create the services the application requires. This guide explains what [providers](#providers) are later. -block register-provider-ngmodule - :marked - You can either register a provider within an [NgModule](ngmodule.html) or in application components. +:marked + You can either register a provider within an [NgModule](ngmodule.html) or in application components. - a#register-providers-ngmodule - :marked - ### Registering providers in an _NgModule_ - Here's the `AppModule` that registers two providers, `UserService` and an `APP_CONFIG` provider, - in its `providers` !{_array}. +a#register-providers-ngmodule +:marked + ### Registering providers in an _NgModule_ + Here's the `AppModule` that registers two providers, `UserService` and an `APP_CONFIG` provider, + in its `providers` array. - - var app_module_ts = 'src/app/app.module.ts'; - +makeExcerpt(app_module_ts + ' (excerpt)', 'ngmodule', app_module_ts) ++makeExcerpt('src/app/app.module.ts (excerpt)', 'ngmodule', app_module_ts) :marked Because the `HeroService` is used _only_ within the `HeroesComponent` and its subcomponents, the top-level `HeroesComponent` is the ideal @@ -300,31 +292,30 @@ a#register-providers-component :marked ### Registering providers in a component - Here's a revised `HeroesComponent` that registers the `HeroService` in its `providers` !{_array}. + Here's a revised `HeroesComponent` that registers the `HeroService` in its `providers` array. +makeExample('src/app/heroes/heroes.component.1.ts', 'full', 'src/app/heroes/heroes.component.ts', stylePattern)(format='.') -block ngmodule-vs-component - a#ngmodule-vs-comp +a#ngmodule-vs-comp +:marked + ### When to use _NgModule_ versus an application component + + On the one hand, a provider in an `NgModule` is registered in the root injector. That means that every provider + registered within an `NgModule` will be accessible in the _entire application_. + + On the other hand, a provider registered in an application component is available only on + that component and all its children. + + Here, the `APP_CONFIG` service needs to be available all across the application, so it's + registered in the `AppModule` `@NgModule` `providers` array. + But since the `HeroService` is only used within the *Heroes* + feature area and nowhere else, it makes sense to register it in + the `HeroesComponent`. + +.l-sub-section :marked - ### When to use _NgModule_ versus an application component - - On the one hand, a provider in an `NgModule` is registered in the root injector. That means that every provider - registered within an `NgModule` will be accessible in the _entire application_. - - On the other hand, a provider registered in an application component is available only on - that component and all its children. - - Here, the `APP_CONFIG` service needs to be available all across the application, so it's - registered in the `AppModule` `@NgModule` `providers` !{_array}. - But since the `HeroService` is only used within the *Heroes* - feature area and nowhere else, it makes sense to register it in - the `HeroesComponent`. - - .l-sub-section - :marked - Also see *"Should I add app-wide providers to the root `AppModule` or - the root `AppComponent`?"* in the [NgModule FAQ](../cookbook/ngmodule-faq.html#q-root-component-or-module). + Also see *"Should I add app-wide providers to the root `AppModule` or + the root `AppComponent`?"* in the [NgModule FAQ](../cookbook/ngmodule-faq.html#q-root-component-or-module). a#prep-for-injection :marked @@ -352,12 +343,12 @@ a#prep-for-injection :marked Note that the constructor parameter has the type `HeroService`, and that - the `HeroListComponent` class has an `@Component` #{_decorator} + the `HeroListComponent` class has an `@Component` decorator (scroll up to confirm that fact). Also recall that the parent component (`HeroesComponent`) has `providers` information for `HeroService`. - The constructor parameter type, the `@Component` #{_decorator}, + The constructor parameter type, the `@Component` decorator, and the parent's `providers` information combine to tell the Angular injector to inject an instance of `HeroService` whenever it creates a new `HeroListComponent`. @@ -432,37 +423,35 @@ a#service-needs-service src/app/heroes/hero.service (v1)`) :marked - The constructor now asks for an injected instance of a `Logger` and stores it in a private property called `#{_priv}logger`. + The constructor now asks for an injected instance of a `Logger` and stores it in a private property called `logger`. You call that property within the `getHeroes()` method when anyone asks for heroes. -- var injUrl = '../api/core/index/Injectable-decorator.html'; a#injectable :marked ### Why _@Injectable()_? - **@Injectable()** marks a class as available to an + **@Injectable()** marks a class as available to an injector for instantiation. Generally speaking, an injector reports an error when trying to instantiate a class that is not marked as `@Injectable()`. -block injectable-not-always-needed-in-ts - .l-sub-section - :marked - As it happens, you could have omitted `@Injectable()` from the first - version of `HeroService` because it had no injected parameters. - But you must have it now that the service has an injected dependency. - You need it because Angular requires constructor parameter metadata - in order to inject a `Logger`. +.l-sub-section + :marked + As it happens, you could have omitted `@Injectable()` from the first + version of `HeroService` because it had no injected parameters. + But you must have it now that the service has an injected dependency. + You need it because Angular requires constructor parameter metadata + in order to inject a `Logger`. - .callout.is-helpful - header Suggestion: add @Injectable() to every service class - :marked - Consider adding `@Injectable()` to every service class, even those that don't have dependencies - and, therefore, do not technically require it. Here's why: +.callout.is-helpful + header Suggestion: add @Injectable() to every service class + :marked + Consider adding `@Injectable()` to every service class, even those that don't have dependencies + and, therefore, do not technically require it. Here's why: - ul(style="font-size:inherit") - li Future proofing: No need to remember @Injectable() when you add a dependency later. - li Consistency: All services follow the same rules, and you don't have to wonder why #{_a} #{_decorator} is missing. + ul(style="font-size:inherit") + li Future proofing: No need to remember @Injectable() when you add a dependency later. + li Consistency: All services follow the same rules, and you don't have to wonder why a decorator is missing. :marked Injectors are also responsible for instantiating components @@ -471,35 +460,33 @@ block injectable-not-always-needed-in-ts You *can* add it if you really want to. It isn't necessary because the `HeroesComponent` is already marked with `@Component`, and this - !{_decorator} class (like `@Directive` and `@Pipe`, which you learn about later) - is a subtype of @Injectable(). It is in - fact `@Injectable()` #{_decorator}s that + decorator class (like `@Directive` and `@Pipe`, which you learn about later) + is a subtype of @Injectable(). It is in + fact `@Injectable()` decorators that identify a class as a target for instantiation by an injector. -+ifDocsFor('ts') - .l-sub-section - :marked - At runtime, injectors can read class metadata in the transpiled JavaScript code - and use the constructor parameter type information - to determine what things to inject. +.l-sub-section + :marked + At runtime, injectors can read class metadata in the transpiled JavaScript code + and use the constructor parameter type information + to determine what things to inject. - Not every JavaScript class has metadata. - The TypeScript compiler discards metadata by default. - If the `emitDecoratorMetadata` compiler option is true - (as it should be in the `tsconfig.json`), - the compiler adds the metadata to the generated JavaScript - for _every class with at least one decorator_. + Not every JavaScript class has metadata. + The TypeScript compiler discards metadata by default. + If the `emitDecoratorMetadata` compiler option is true + (as it should be in the `tsconfig.json`), + the compiler adds the metadata to the generated JavaScript + for _every class with at least one decorator_. - While any decorator will trigger this effect, mark the service class with the - @Injectable() #{_decorator} - to make the intent clear. + While any decorator will trigger this effect, mark the service class with the + @Injectable() decorator + to make the intent clear. .callout.is-critical header Always include the parentheses - block always-include-paren - :marked - Always write `@Injectable()`, not just `@Injectable`. - The application will fail mysteriously if you forget the parentheses. + :marked + Always write `@Injectable()`, not just `@Injectable`. + The application will fail mysteriously if you forget the parentheses. .l-main-section#logger-service :marked @@ -513,13 +500,10 @@ block injectable-not-always-needed-in-ts +makeExample('src/app/logger.service.ts') -block real-logger - //- N/A - :marked You're likely to need the same logger service everywhere in your application, - so put it in the project's `#{_appDir}` folder and - register it in the `providers` #{_array} of the application !{_moduleVsComp}, `!{_AppModuleVsAppComp}`. + so put it in the project's `app` folder and + register it in the `providers` array of the application module, `AppModule`. +makeExcerpt('src/app/providers.component.ts (excerpt)', 'providers-logger','src/app/app.module.ts') @@ -546,51 +530,44 @@ code-example(format="nocode"). You must register a service *provider* with the injector, or it won't know how to create the service. - Earlier you registered the `Logger` service in the `providers` #{_array} of the metadata for the `AppModule` like this: + Earlier you registered the `Logger` service in the `providers` array of the metadata for the `AppModule` like this: +makeExample('dependency-injection/ts/src/app/providers.component.ts','providers-logger') -- var implements = _docsFor == 'dart' ? 'implements' : 'looks and behaves like a ' -- var objectlike = _docsFor == 'dart' ? '' : 'an object that behaves like ' -- var loggerlike = _docsFor == 'dart' ? '' : 'You could provide a logger-like object. ' :marked - There are many ways to *provide* something that #{implements} `Logger`. + There are many ways to *provide* something that looks and behaves like a `Logger`. The `Logger` class itself is an obvious and natural provider. But it's not the only way. - You can configure the injector with alternative providers that can deliver #{objectlike} a `Logger`. - You could provide a substitute class. #{loggerlike} + You can configure the injector with alternative providers that can deliver an object that behaves like a `Logger`. + You could provide a substitute class. You could provide a logger-like object. You could give it a provider that calls a logger factory function. Any of these approaches might be a good choice under the right circumstances. What matters is that the injector has a provider to go to when it needs a `Logger`. //- Dart limitation: the provide function isn't const so it cannot be used in an annotation. -- var _andProvideFn = _docsFor == 'dart' ? '' : 'and provide object literal'; + #provide :marked - ### The *Provider* class !{_andProvideFn} + ### The *Provider* class and _provide_ object literal :marked - You wrote the `providers` #{_array} like this: + You wrote the `providers` array like this: +makeExample('dependency-injection/ts/src/app/providers.component.ts','providers-1') -block provider-shorthand - :marked - This is actually a shorthand expression for a provider registration - using a _provider_ object literal with two properties: +:marked + This is actually a shorthand expression for a provider registration + using a _provider_ object literal with two properties: +makeExample('dependency-injection/ts/src/app/providers.component.ts','providers-3') -block provider-ctor-args - - var _secondParam = 'provider definition object'; - :marked The first is the [token](#token) that serves as the key for both locating a dependency value and registering the provider. - The second is a !{_secondParam}, + The second is a provider definition object, which you can think of as a *recipe* for creating the dependency value. There are many ways to create dependency values just as there are many ways to write a recipe. @@ -604,9 +581,6 @@ block provider-ctor-args +makeExample('dependency-injection/ts/src/app/providers.component.ts','providers-4') -block dart-diff-const-metadata - //- N/A - a#class-provider-dependencies :marked ### Class provider with dependencies @@ -653,9 +627,6 @@ a#value-provider :marked Sometimes it's easier to provide a ready-made object rather than ask the injector to create it from a class. -block dart-diff-const-metadata-ctor - //- N/A - +makeExample('dependency-injection/ts/src/app/providers.component.ts','silent-logger')(format=".") :marked @@ -720,19 +691,17 @@ block dart-diff-const-metadata-ctor The `useFactory` field tells Angular that the provider is a factory function whose implementation is the `heroServiceFactory`. - The `deps` property is #{_an} #{_array} of [provider tokens](#token). + The `deps` property is an array of [provider tokens](#token). The `Logger` and `UserService` classes serve as tokens for their own class providers. The injector resolves these tokens and injects the corresponding services into the matching factory function parameters. -- var exportedvar = _docsFor == 'dart' ? 'constant' : 'exported variable' -- var variable = _docsFor == 'dart' ? 'constant' : 'variable' :marked - Notice that you captured the factory provider in #{_an} #{exportedvar}, `heroServiceProvider`. + Notice that you captured the factory provider in an exported variable, `heroServiceProvider`. This extra step makes the factory provider reusable. - You can register the `HeroService` with this #{variable} wherever you need it. + You can register the `HeroService` with this variable wherever you need it. In this sample, you need it only in the `HeroesComponent`, - where it replaces the previous `HeroService` registration in the metadata `providers` #{_array}. + where it replaces the previous `HeroService` registration in the metadata `providers` array. Here you see the new and the old implementation side-by-side: +makeTabs( @@ -774,14 +743,12 @@ a#non-class-dependencies ### Non-class dependencies p | What if the dependency value isn't a class? Sometimes the thing you want to inject is a - block non-class-dep-eg - | span string, function, or object. + | span string, function, or object. p | Applications often define configuration objects with lots of small facts | (like the title of the application or the address of a web API endpoint) - block config-obj-maps - | but these configuration objects aren't always instances of a class. - | They can be object literals such as this one: + | but these configuration objects aren't always instances of a class. + | They can be object literals such as this one: +makeExample('dependency-injection/ts/src/app/app.config.ts','config','src/app/app-config.ts (excerpt)')(format='.') @@ -789,36 +756,33 @@ p What if you'd like to make this configuration object available for injection? You know you can register an object with a [value provider](#value-provider). -block what-should-we-use-as-token +:marked + But what should you use as the token? + You don't have a class to serve as a token. + There is no `AppConfig` class. + +.l-sub-section#interface :marked - But what should you use as the token? - You don't have a class to serve as a token. - There is no `AppConfig` class. + ### TypeScript interfaces aren't valid tokens - .l-sub-section#interface - :marked - ### TypeScript interfaces aren't valid tokens + The `HERO_DI_CONFIG` constant has an interface, `AppConfig`. Unfortunately, you + cannot use a TypeScript interface as a token: + +makeExample('dependency-injection/ts/src/app/providers.component.ts','providers-9-interface')(format=".") + +makeExample('dependency-injection/ts/src/app/providers.component.ts','provider-9-ctor-interface')(format=".") + :marked + That seems strange if you're used to dependency injection in strongly typed languages, where + an interface is the preferred dependency lookup key. - The `HERO_DI_CONFIG` constant has an interface, `AppConfig`. Unfortunately, you - cannot use a TypeScript interface as a token: - +makeExample('dependency-injection/ts/src/app/providers.component.ts','providers-9-interface')(format=".") - +makeExample('dependency-injection/ts/src/app/providers.component.ts','provider-9-ctor-interface')(format=".") - :marked - That seems strange if you're used to dependency injection in strongly typed languages, where - an interface is the preferred dependency lookup key. + It's not Angular's doing. An interface is a TypeScript design-time artifact. JavaScript doesn't have interfaces. + The TypeScript interface disappears from the generated JavaScript. + There is no interface type information left for Angular to find at runtime. - It's not Angular's doing. An interface is a TypeScript design-time artifact. JavaScript doesn't have interfaces. - The TypeScript interface disappears from the generated JavaScript. - There is no interface type information left for Angular to find at runtime. - -//- FIXME update once https://github.com/dart-lang/angular2/issues/16 is addressed. -- var opaquetoken = _docsFor == 'dart' ? 'OpaqueToken' : 'OpaqueToken' a#opaquetoken :marked ### _OpaqueToken_ One solution to choosing a provider token for non-class dependencies is - to define and use an !{opaquetoken}. + to define and use an OpaqueToken. The definition looks like this: +makeExample('dependency-injection/ts/src/app/app.config.ts','token')(format='.') @@ -830,19 +794,17 @@ a#opaquetoken :marked Now you can inject the configuration object into any constructor that needs it, with - the help of an `@Inject` #{_decorator}: + the help of an `@Inject` decorator: +makeExample('dependency-injection/ts/src/app/app.component.2.ts','ctor')(format=".") -- var configType = _docsFor == 'dart' ? 'Map' : 'AppConfig' .l-sub-section :marked - Although the !{configType} interface plays no role in dependency injection, + Although the `AppConfig` interface plays no role in dependency injection, it supports typing of the configuration object within the class. -block dart-map-alternative - :marked - Aternatively, you can provide and inject the configuration object in an ngModule like `AppModule`. +:marked + Aternatively, you can provide and inject the configuration object in an ngModule like `AppModule`. +makeExcerpt('src/app/app.module.ts','ngmodule-providers') @@ -855,8 +817,7 @@ block dart-map-alternative You can tell Angular that the dependency is optional by annotating the constructor argument with `@Optional()`: -+ifDocsFor('ts') - +makeExample('dependency-injection/ts/src/app/providers.component.ts','import-optional', '') ++makeExample('dependency-injection/ts/src/app/providers.component.ts','import-optional', '') +makeExample('dependency-injection/ts/src/app/providers.component.ts','provider-10-ctor', '')(format='.') :marked @@ -915,23 +876,22 @@ block dart-map-alternative Framework developers may take this approach when they must acquire services generically and dynamically. -+ifDocsFor('ts') - .l-main-section#one-class-per-file +.l-main-section#one-class-per-file +:marked + ## Appendix: Why have one class per file + + Having multiple classes in the same file is confusing and best avoided. + Developers expect one class per file. Keep them happy. + + If you combine the `HeroService` class with + the `HeroesComponent` in the same file, + **define the component last**. + If you define the component before the service, + you'll get a runtime null reference error. + +.l-sub-section :marked - ## Appendix: Why have one class per file - - Having multiple classes in the same file is confusing and best avoided. - Developers expect one class per file. Keep them happy. - - If you combine the `HeroService` class with - the `HeroesComponent` in the same file, - **define the component last**. - If you define the component before the service, - you'll get a runtime null reference error. - - .l-sub-section - :marked - You actually can define the component first with the help of the `forwardRef()` method as explained - in this [blog post](http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html). - But why flirt with trouble? - Avoid the problem altogether by defining components and services in separate files. + You actually can define the component first with the help of the `forwardRef()` method as explained + in this [blog post](http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html). + But why flirt with trouble? + Avoid the problem altogether by defining components and services in separate files. diff --git a/public/docs/ts/latest/guide/deployment.jade b/public/docs/ts/latest/guide/deployment.jade index 7f44f9f9cf..ea3c170c29 100644 --- a/public/docs/ts/latest/guide/deployment.jade +++ b/public/docs/ts/latest/guide/deployment.jade @@ -156,7 +156,7 @@ a#node-modules Practice with this sample before attempting these techniques on your application. 1. Follow the [setup instructions](../guide/setup.html "Angular QuickStart setup") for creating a new project - named . + named simple-deployment. 1. Add the "Simple deployment" sample files shown above. diff --git a/public/docs/ts/latest/guide/displaying-data.jade b/public/docs/ts/latest/guide/displaying-data.jade index 6584a1d170..772d63ae3b 100644 --- a/public/docs/ts/latest/guide/displaying-data.jade +++ b/public/docs/ts/latest/guide/displaying-data.jade @@ -1,7 +1,5 @@ block includes include ../_util-fns - - var _iterableUrl = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols'; - - var _boolean = 'truthy/falsy'; :marked You can display data by binding controls in an HTML template to properties of an Angular component. @@ -19,7 +17,7 @@ figure.image-display # Contents * [Showing component properties with interpolation](#interpolation). - * [Showing !{_an} !{_array} property with NgFor](#ngFor). + * [Showing an array property with NgFor](#ngFor). * [Conditional display with NgIf](#ngIf). .l-sub-section @@ -35,9 +33,9 @@ figure.image-display With interpolation, you put the property name in the view template, enclosed in double curly braces: `{{myHero}}`. Follow the [setup](setup.html) instructions for creating a new project - named . + named displaying-data. - Then modify the file by + Then modify the app.component.ts file by changing the template and the body of the component. When you're done, it should look like this: @@ -52,13 +50,12 @@ figure.image-display +makeExcerpt('src/app/app.component.1.ts', 'template', '') -+ifDocsFor('ts') - .l-sub-section - :marked - The template is a multi-line string within ECMAScript 2015 backticks (\`). - The backtick (\`)—which is *not* the same character as a single - quote (`'`)—allows you to compose a string over several lines, which makes the - HTML more readable. +.l-sub-section + :marked + The template is a multi-line string within ECMAScript 2015 backticks (\`). + The backtick (\`)—which is *not* the same character as a single + quote (`'`)—allows you to compose a string over several lines, which makes the + HTML more readable. :marked Angular automatically pulls the value of the `title` and `myHero` properties from the component and @@ -74,13 +71,13 @@ figure.image-display Notice that you don't call **new** to create an instance of the `AppComponent` class. Angular is creating an instance for you. How? - The CSS `selector` in the `@Component` !{_decorator} specifies an element named ``. + The CSS `selector` in the `@Component` decorator specifies an element named ``. That element is a placeholder in the body of your `index.html` file: +makeExcerpt('src/index.html', 'body') :marked - When you bootstrap with the `AppComponent` class (in ), Angular looks for a `` + When you bootstrap with the `AppComponent` class (in main.ts), Angular looks for a `` in the `index.html`, finds it, instantiates an instance of `AppComponent`, and renders it inside the `` tag. @@ -88,9 +85,8 @@ figure.image-display figure.image-display img(src="/resources/images/devguide/displaying-data/title-and-hero.png" alt="Title and Hero") -+ifDocsFor('ts') - :marked - The next few sections review some of the coding choices in the app. +:marked + The next few sections review some of the coding choices in the app. :marked ## Template inline or template file? @@ -98,7 +94,7 @@ figure.image-display You can store your component's template in one of two places. You can define it *inline* using the `template` property, or you can define the template in a separate HTML file and link to it in - the component metadata using the `@Component` !{_decorator}'s `templateUrl` property. + the component metadata using the `@Component` decorator's `templateUrl` property. The choice between inline and separate HTML is a matter of taste, circumstances, and organization policy. @@ -107,22 +103,21 @@ figure.image-display In either style, the template data bindings have the same access to the component's properties. -+ifDocsFor('ts') - :marked - ## Constructor or variable initialization? +:marked + ## Constructor or variable initialization? - Although this example uses variable assignment to initialize the components, you can instead declare and initialize the properties using a constructor: + Although this example uses variable assignment to initialize the components, you can instead declare and initialize the properties using a constructor: - +makeExcerpt('src/app/app-ctor.component.ts', 'class') ++makeExcerpt('src/app/app-ctor.component.ts', 'class') - :marked - This app uses more terse "variable assignment" style simply for brevity. +:marked + This app uses more terse "variable assignment" style simply for brevity. .l-main-section#ngFor :marked - ## Showing !{_an} !{_array} property with ***ngFor** + ## Showing an array property with ***ngFor** - To display a list of heroes, begin by adding !{_an} !{_array} of hero names to the component and redefine `myHero` to be the first name in the !{_array}. + To display a list of heroes, begin by adding an array of hero names to the component and redefine `myHero` to be the first name in the array. +makeExcerpt('src/app/app.component.2.ts', 'class') @@ -156,8 +151,8 @@ figure.image-display .l-sub-section :marked - In this case, `ngFor` is displaying !{_an} !{_array}, but `ngFor` can - repeat items for any [iterable](!{_iterableUrl}) object. + In this case, `ngFor` is displaying an array, but `ngFor` can + repeat items for any [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) object. :marked Now the heroes appear in an unordered list. @@ -171,38 +166,37 @@ figure.image-display The app's code defines the data directly inside the component, which isn't best practice. In a simple demo, however, it's fine. - At the moment, the binding is to !{_an} !{_array} of strings. + At the moment, the binding is to an array of strings. In real applications, most bindings are to more specialized objects. - To convert this binding to use specialized objects, turn the !{_array} - of hero names into !{_an} !{_array} of `Hero` objects. For that you'll need a `Hero` class. + To convert this binding to use specialized objects, turn the array + of hero names into an array of `Hero` objects. For that you'll need a `Hero` class. - Create a new file in the `!{_appDir}` folder called with the following code: + Create a new file in the `app` folder called `hero.ts` with the following code: +makeExcerpt('src/app/hero.ts') -block hero-class - :marked - You've defined a class with a constructor and two properties: `id` and `name`. +:marked + You've defined a class with a constructor and two properties: `id` and `name`. - It might not look like the class has properties, but it does. - The declaration of the constructor parameters takes advantage of a TypeScript shortcut. + It might not look like the class has properties, but it does. + The declaration of the constructor parameters takes advantage of a TypeScript shortcut. - Consider the first parameter: + Consider the first parameter: - +makeExcerpt('src/app/hero.ts ()', 'id') ++makeExcerpt('src/app/hero.ts ()', 'id') - :marked - That brief syntax does a lot: - * Declares a constructor parameter and its type. - * Declares a public property of the same name. - * Initializes that property with the corresponding argument when creating an instance of the class. +:marked + That brief syntax does a lot: + * Declares a constructor parameter and its type. + * Declares a public property of the same name. + * Initializes that property with the corresponding argument when creating an instance of the class. .l-main-section :marked ## Using the Hero class - After importing the `Hero` class, the `AppComponent.heroes` property can return a _typed_ !{_array} + After importing the `Hero` class, the `AppComponent.heroes` property can return a _typed_ array of `Hero` objects: +makeExcerpt('src/app/app.component.3.ts', 'heroes') @@ -225,7 +219,7 @@ block hero-class Let's change the example to display a message if there are more than three heroes. - The Angular `ngIf` directive inserts or removes an element based on a !{_boolean} condition. + The Angular `ngIf` directive inserts or removes an element based on a _truthy/falsy_ condition. To see it in action, add the following paragraph at the bottom of the template: +makeExcerpt('src/app/app.component.ts', 'message') @@ -237,7 +231,7 @@ block hero-class :marked The template expression inside the double quotes, - `*ngIf="heros.length > 3"`, looks and behaves much like !{_Lang}. + `*ngIf="heros.length > 3"`, looks and behaves much like TypeScript. When the component's list of heroes has more than three items, Angular adds the paragraph to the DOM and the message appears. If there are three or fewer items, Angular omits the paragraph, so no message appears. For more information, @@ -250,8 +244,8 @@ block hero-class big chunks of HTML with many data bindings. :marked - Try it out. Because the !{_array} has four items, the message should appear. - Go back into and delete or comment out one of the elements from the hero !{_array}. + Try it out. Because the array has four items, the message should appear. + Go back into app.component.ts" and delete or comment out one of the elements from the hero array. The browser should refresh automatically and the message should disappear. .l-main-section @@ -259,16 +253,15 @@ block hero-class ## Summary Now you know how to use: - **Interpolation** with double curly braces to display a component property. - - **ngFor** to display !{_an} !{_array} of items. - - A !{_Lang} class to shape the **model data** for your component and display properties of that model. + - **ngFor** to display an array of items. + - A TypeScript class to shape the **model data** for your component and display properties of that model. - **ngIf** to conditionally display a chunk of HTML based on a boolean expression. Here's the final code: -block final-code - +makeTabs(`displaying-data/ts/src/app/app.component.ts, - displaying-data/ts/src/app/hero.ts, - displaying-data/ts/src/app/app.module.ts, - displaying-data/ts/src/main.ts`, - 'final,,,', - 'src/app/app.component.ts, src/app/hero.ts, src/app/app.module.ts, main.ts') ++makeTabs(`displaying-data/ts/src/app/app.component.ts, + displaying-data/ts/src/app/hero.ts, + displaying-data/ts/src/app/app.module.ts, + displaying-data/ts/src/main.ts`, + 'final,,,', + 'src/app/app.component.ts, src/app/hero.ts, src/app/app.module.ts, main.ts') diff --git a/public/docs/ts/latest/guide/forms.jade b/public/docs/ts/latest/guide/forms.jade index 93102adcc7..a27156a43e 100644 --- a/public/docs/ts/latest/guide/forms.jade +++ b/public/docs/ts/latest/guide/forms.jade @@ -83,7 +83,7 @@ figure.image-display ## Setup Follow the [setup](setup.html) instructions for creating a new project - named angular-forms. + named angular-forms. ## Create the Hero model class @@ -94,7 +94,7 @@ figure.image-display That describes well the `Hero` class with its three required fields (`id`, `name`, `power`) and one optional field (`alterEgo`). - In the `!{_appDir}` directory, create the following file with the given content: + In the `app` directory, create the following file with the given content: +makeExample('src/app/hero.ts') diff --git a/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade b/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade index a1dc5c4d1f..456d15e7af 100644 --- a/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade +++ b/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade @@ -70,7 +70,7 @@ figure.image-display It effectively "reconfigures" and "shadows" a provider at a higher level in the tree. If you only specify providers at the top level (typically the root `AppModule`), the tree of injectors appears to be flat. - All requests bubble up to the root NgModule injector that you configured with the `!{_bootstrapModule}` method. + All requests bubble up to the root NgModule injector that you configured with the `bootstrapModule` method. .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 ecdb8f4947..0da9407b5d 100644 --- a/public/docs/ts/latest/guide/lifecycle-hooks.jade +++ b/public/docs/ts/latest/guide/lifecycle-hooks.jade @@ -1,8 +1,6 @@ block includes include ../_util-fns -- var top="vertical-align:top" - figure img(src="/resources/images/devguide/lifecycle-hooks/hooks-in-sequence.png" alt="Us" align="left" style="width:200px; margin-left:-40px;margin-right:30px") @@ -17,6 +15,7 @@ figure A directive has the same set of lifecycle hooks, minus the hooks that are specific to component content and views.
    +<<<<<<< 93d3db1fd4f61c9c6078b2000dea164c87fa071c +ifDocsFor('ts|js') :marked ## Contents @@ -38,6 +37,28 @@ figure * [Content projection](#content-projection) * [AfterContent hooks](#aftercontent-hooks) * [No unidirectional flow worries with _AfterContent_](#no-unidirectional-flow-worries) +======= + +:marked + ## Contents + * [Component lifecycle hooks overview](#hooks-overview) + * [Lifecycle sequence](#hooks-purpose-timing) + * [Interfaces are optional (technically)](#interface-optional) + * [Other Angular lifecycle hooks](#other-lifecycle-hooks) + * [Lifecycle examples](#the-sample) + * [Peek-a-boo: all hooks](#peek-a-boo) + * [Spying OnInit and OnDestroy](#spy) + * [OnInit](#oninit) + * [OnDestroy](#ondestroy) + * [OnChanges](#onchanges) + * [DoCheck](#docheck) + * [AfterView](#afterview) + * [Abide by the unidirectional data flow rule](#wait-a-tick) + * [AfterContent](#aftercontent) + * [Content projection](#content-projection) + * [AfterContent hooks](#aftercontent-hooks) + * [No unidirectional flow worries with _AfterContent_](#no-unidirectional-flow-worries) +>>>>>>> chore: remove dart remains :marked Try the . @@ -72,7 +93,7 @@ table(width="100%") th Hook th Purpose and Timing - tr(style=top) + tr(style=vertical-align:top) td ngOnChanges() td :marked @@ -81,7 +102,7 @@ table(width="100%") Called before `ngOnInit()` and whenever one or more data-bound input properties change. - tr(style=top) + tr(style=vertical-align:top) td ngOnInit() td :marked @@ -90,7 +111,7 @@ table(width="100%") Called _once_, after the _first_ `ngOnChanges()`. - tr(style=top) + tr(style=vertical-align:top) td ngDoCheck() td :marked @@ -98,7 +119,7 @@ table(width="100%") Called during every change detection run, immediately after `ngOnChanges()` and `ngOnInit()`. - tr(style=top) + tr(style=vertical-align:top) td ngAfterContentInit() td :marked @@ -108,7 +129,7 @@ table(width="100%") _A component-only hook_. - tr(style=top) + tr(style=vertical-align:top) td ngAfterContentChecked() td :marked @@ -118,7 +139,7 @@ table(width="100%") _A component-only hook_. - tr(style=top) + tr(style=vertical-align:top) td ngAfterViewInit() td :marked @@ -128,7 +149,7 @@ table(width="100%") _A component-only hook_. - tr(style=top) + tr(style=vertical-align:top) td ngAfterViewChecked() td :marked @@ -138,7 +159,7 @@ table(width="100%") _A component-only hook_. - tr(style=top) + tr(style=vertical-align:top) td ngOnDestroy td :marked @@ -147,24 +168,23 @@ table(width="100%") Called _just before_ Angular destroys the directive/component. -+ifDocsFor('ts|js') - a#interface-optional - .l-main-section - :marked - ## Interfaces are optional (technically) +a#interface-optional +.l-main-section +:marked + ## Interfaces are optional (technically) - The interfaces are optional for JavaScript and Typescript developers from a purely technical perspective. - The JavaScript language doesn't have interfaces. - Angular can't see TypeScript interfaces at runtime because they disappear from the transpiled JavaScript. + The interfaces are optional for JavaScript and Typescript developers from a purely technical perspective. + The JavaScript language doesn't have interfaces. + Angular can't see TypeScript interfaces at runtime because they disappear from the transpiled JavaScript. - Fortunately, they aren't necessary. - You don't have to add the lifecycle hook interfaces to directives and components to benefit from the hooks themselves. + Fortunately, they aren't necessary. + You don't have to add the lifecycle hook interfaces to directives and components to benefit from the hooks themselves. - Angular instead inspects directive and component classes and calls the hook methods *if they are defined*. - Angular finds and calls methods like `ngOnInit()`, with or without the interfaces. + Angular instead inspects directive and component classes and calls the hook methods *if they are defined*. + Angular finds and calls methods like `ngOnInit()`, with or without the interfaces. - Nonetheless, it's good practice to add interfaces to TypeScript directive classes - in order to benefit from strong typing and editor tooling. + Nonetheless, it's good practice to add interfaces to TypeScript directive classes + in order to benefit from strong typing and editor tooling. a#other-lifecycle-hooks .l-main-section @@ -173,9 +193,6 @@ a#other-lifecycle-hooks Other Angular sub-systems may have their own lifecycle hooks apart from these component hooks. -block other-angular-subsystems - //- N/A for TS. - :marked 3rd party libraries might implement their hooks as well in order to give developers more control over how these libraries are used. @@ -199,13 +216,13 @@ table(width="100%") tr th Component th Description - tr(style=top) + tr(style=vertical-align:top) td Peek-a-boo td :marked Demonstrates every lifecycle hook. Each hook method writes to the on-screen log. - tr(style=top) + tr(style=vertical-align:top) td Spy td :marked @@ -215,33 +232,33 @@ table(width="100%") This example applies the `SpyDirective` to a `

    ` in an `ngFor` *hero* repeater managed by the parent `SpyComponent`. - tr(style=top) + tr(style=vertical-align:top) td OnChanges td :marked See how Angular calls the `ngOnChanges()` hook with a `changes` object every time one of the component input properties changes. Shows how to interpret the `changes` object. - tr(style=top) + tr(style=vertical-align:top) td DoCheck td :marked Implements an `ngDoCheck()` method with custom change detection. See how often Angular calls this hook and watch it post changes to a log. - tr(style=top) + tr(style=vertical-align:top) td AfterView td :marked Shows what Angular means by a *view*. Demonstrates the `ngAfterViewInit` and `ngAfterViewChecked` hooks. - tr(style=top) + tr(style=vertical-align:top) td AfterContent td :marked Shows how to project external content into a component and how to distinguish projected content from a component's view children. Demonstrates the `ngAfterContentInit` and `ngAfterContentChecked` hooks. - tr(style=top) + tr(style=vertical-align:top) td Counter td :marked @@ -479,10 +496,8 @@ a#wait-a-tick Both of these hooks fire _after_ the component's view has been composed. Angular throws an error if the hook updates the component's data-bound `comment` property immediately (try it!). -block tick-methods - :marked - The `LoggerService.tick_then()` postpones the log update - for one turn of the browser's JavaScript cycle and that's just long enough. + The `LoggerService.tick_then()` postpones the log update + for one turn of the browser's JavaScript cycle and that's just long enough. :marked Here's *AfterView* in action: diff --git a/public/docs/ts/latest/guide/pipes.jade b/public/docs/ts/latest/guide/pipes.jade index bc34258c0e..f9500ab436 100644 --- a/public/docs/ts/latest/guide/pipes.jade +++ b/public/docs/ts/latest/guide/pipes.jade @@ -142,8 +142,8 @@ figure.image-display * There will be one additional argument to the `transform` method for each parameter passed to the pipe. Your pipe has one such parameter: the `exponent`. * To tell Angular that this is a pipe, you apply the - `@Pipe` #{_decorator}, which you import from the core Angular library. - * The `@Pipe` #{_decorator} allows you to define the + `@Pipe` decorator, which you import from the core Angular library. + * The `@Pipe` decorator allows you to define the pipe name that you'll use within template expressions. It must be a valid JavaScript identifier. Your pipe's name is `exponentialStrength`. @@ -161,16 +161,14 @@ figure.image-display figure.image-display img(src='/resources/images/devguide/pipes/power-booster.png' alt="Power Booster") -- var _decls = _docsFor == 'dart' ? 'pipes' : 'declarations'; -- var _appMod = _docsFor == 'dart' ? '@Component' : 'AppModule'; :marked Note the following: * You use your custom pipe the same way you use built-in pipes. - * You must include your pipe in the `!{_decls}` #{_array} of the `!{_appMod}`. + * You must include your pipe in the `declarations` array of the `AppModule`. .callout.is-helpful - header Remember the !{_decls} #{_array} + header Remember the declarations array :marked You must manually register custom pipes. If you don't, Angular reports an error. @@ -206,17 +204,17 @@ a#change-detection ### No pipe In the next example, the component uses the default, aggressive change detection strategy to monitor and update - its display of every hero in the `heroes` #{_array}. Here's the template: + its display of every hero in the `heroes` array. Here's the template: +makeExample('pipes/ts/src/app/flying-heroes.component.html', 'template-1', 'src/app/flying-heroes.component.html (v1)')(format='.') :marked - The companion component class provides heroes, adds heroes into the #{_array}, and can reset the #{_array}. + The companion component class provides heroes, adds heroes into the array, and can reset the array. +makeExample('pipes/ts/src/app/flying-heroes.component.ts', 'v1', 'src/app/flying-heroes.component.ts (v1)')(format='.') :marked You can add heroes and Angular updates the display when you do. - If you click the `reset` button, Angular replaces `heroes` with a new #{_array} of the original heroes and updates the display. + If you click the `reset` button, Angular replaces `heroes` with a new array of the original heroes and updates the display. If you added the ability to remove or change a hero, Angular would detect those changes and update the display as well. ### Flying-heroes pipe @@ -237,15 +235,15 @@ a#change-detection Notice how a hero is added: +makeExample('pipes/ts/src/app/flying-heroes.component.ts', 'push')(format='.') :marked - You add the hero into the `heroes` #{_array}. The reference to the #{_array} hasn't changed. - It's the same #{_array}. That's all Angular cares about. From its perspective, *same #{_array}, no change, no display update*. + You add the hero into the `heroes` array. The reference to the array hasn't changed. + It's the same array. That's all Angular cares about. From its perspective, *same array, no change, no display update*. - To fix that, create an #{_array} with the new hero appended and assign that to `heroes`. - This time Angular detects that the #{_array} reference has changed. - It executes the pipe and updates the display with the new #{_array}, which includes the new flying hero. + To fix that, create an array with the new hero appended and assign that to `heroes`. + This time Angular detects that the array reference has changed. + It executes the pipe and updates the display with the new array, which includes the new flying hero. - If you *mutate* the #{_array}, no pipe is invoked and the display isn't updated; - if you *replace* the #{_array}, the pipe executes and the display is updated. + If you *mutate* the array, no pipe is invoked and the display isn't updated; + if you *replace* the array, the pipe executes and the display is updated. The Flying Heroes application extends the code with checkbox switches and additional displays to help you experience these effects. @@ -253,8 +251,8 @@ figure.image-display img(src='/resources/images/devguide/pipes/flying-heroes-anim.gif' alt="Flying Heroes") :marked - Replacing the #{_array} is an efficient way to signal Angular to update the display. - When do you replace the #{_array}? When the data change. + Replacing the array is an efficient way to signal Angular to update the display. + When do you replace the array? When the data change. That's an easy rule to follow in *this* example where the only way to change the data is by adding a hero. @@ -289,7 +287,7 @@ figure.image-display or a changed object reference (`Date`, `Array`, `Function`, `Object`). Angular ignores changes within (composite) objects. - It won't call a pure pipe if you change an input month, add to an input #{_array}, or update an input object property. + It won't call a pure pipe if you change an input month, add to an input array, or update an input object property. This may seem restrictive but it's also fast. An object reference check is fast—much faster than a deep check for @@ -335,28 +333,25 @@ figure.image-display :marked You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`. -- var _fnSuffix = _docsFor == 'dart' ? '.component.ts' : '-impure.component.html'; -- var _region = _docsFor == 'dart' ? 'impure-component' : 'template-flying-heroes'; -+makeExcerpt('src/app/flying-heroes' + _fnSuffix + ' (excerpt)', _region) ++makeExcerpt('src/app/flying-heroes-impure.component.html (excerpt)', 'template-flying-heroes') :marked The only substantive change is the pipe in the template. You can confirm in the that the _flying heroes_ - display updates as you add heroes, even when you mutate the `heroes` #{_array}. + display updates as you add heroes, even when you mutate the `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 + The `AsyncPipe` accepts a `Promise` or `Observable` as input and subscribes to the input automatically, eventually returning the emitted values. The `AsyncPipe` is also stateful. - The pipe maintains a subscription to the input `#{_Observable}` and - keeps delivering values from that `#{_Observable}` as they arrive. + The pipe maintains a subscription to the input `Observable` and + keeps delivering values from that `Observable` as they arrive. - This next example binds an `#{_Observable}` of message strings - (`message#{_dollar}`) to a view with the `async` pipe. + This next example binds an `Observable` of message strings + (`message$`) to a view with the `async` pipe. +makeExample('pipes/ts/src/app/hero-async-message.component.ts', null, 'src/app/hero-async-message.component.ts') @@ -375,7 +370,7 @@ h3#async-pipe The impure #[i AsyncPipe] If you're not careful, this pipe will punish the server with requests. In the following code, the pipe only calls the server when the request URL changes and it caches the server response. - The code uses the [Angular http](server-communication.html) client to retrieve data: + The code uses the [Angular http](server-communication.html) client to retrieve data: +makeExample('src/app/fetch-json.pipe.ts') :marked diff --git a/public/docs/ts/latest/guide/router.jade b/public/docs/ts/latest/guide/router.jade index 20f0792662..bbc1a8ec6d 100644 --- a/public/docs/ts/latest/guide/router.jade +++ b/public/docs/ts/latest/guide/router.jade @@ -1543,8 +1543,8 @@ a#milestone-4 Begin by imitating the heroes feature: - Delete the placeholder crisis center file. - - Create !{_an} `!{_appDir}/crisis-center` folder. - - Copy the files from `!{_appDir}/heroes` into the new crisis center folder. + - Create an `app/crisis-center` folder. + - Copy the files from `app/heroes` into the new crisis center folder. - In the new files, change every mention of "hero" to "crisis", and "heroes" to "crises". You'll turn the `CrisisService` into a purveyor of mock crises instead of mock heroes: @@ -1560,7 +1560,7 @@ a#milestone-4 :marked In keeping with the *Separation of Concerns* principle, - changes to the *Crisis Center* won't affect the `!{_AppModuleVsAppComp}` or + changes to the *Crisis Center* won't affect the `AppModule` or any other feature's component. a#crisis-child-routes :marked @@ -2288,7 +2288,7 @@ a#CanDeactivate +makeExcerpt('src/app/crisis-center/crisis-center-routing.module.3.ts (can deactivate guard)', '') :marked - Add the `Guard` to the main `AppRoutingModule` `providers` !{_array} so the + Add the `Guard` to the main `AppRoutingModule` `providers` array so the `Router` can inject it during the navigation process. +makeExample('src/app/app-routing.module.4.ts', '', '') @@ -2350,7 +2350,7 @@ a#fetch-before-navigating Import this resolver in the `crisis-center-routing.module.ts` and add a `resolve` object to the `CrisisDetailComponent` route configuration. - Remember to add the `CrisisDetailResolver` service to the `CrisisCenterRoutingModule`'s `providers` !{_array}. + Remember to add the `CrisisDetailResolver` service to the `CrisisCenterRoutingModule`'s `providers` array. +makeExcerpt('src/app/crisis-center/crisis-center-routing.module.4.ts (resolver)', 'crisis-detail-resolver') @@ -2549,7 +2549,7 @@ a#can-load-guard The `checkLogin()` method redirects to that URL once the user has logged in. Now import the `AuthGuard` into the `AppRoutingModule` and add the `AuthGuard` to the `canLoad` - !{_array} for the `admin` route. + array for the `admin` route. The completed admin route looks like this: +makeExample('router/ts/src/app/app-routing.module.5.ts', 'admin', 'app-routing.module.ts (lazy admin route)') diff --git a/public/docs/ts/latest/guide/security.jade b/public/docs/ts/latest/guide/security.jade index 6ede32c090..5318a11437 100644 --- a/public/docs/ts/latest/guide/security.jade +++ b/public/docs/ts/latest/guide/security.jade @@ -7,18 +7,17 @@ block includes this user?_) and authorization (_What can this user do?_). For more information about the attacks and mitigations described below, see [OWASP Guide Project](https://www.owasp.org/index.php/Category:OWASP_Guide_Project). + +.l-main-section +:marked + # Contents -+ifDocsFor('ts') - .l-main-section - :marked - # Contents - - * [Reporting vulnerabilities](#report-issues). - * [Best practices](#best-practices). - * [Preventing cross-site scripting (XSS)](#xss). - * [Trusting safe values](#bypass-security-apis). - * [HTTP-Level vulnerabilities](#http). - * [Auditing Angular applications](#code-review). + * [Reporting vulnerabilities](#report-issues). + * [Best practices](#best-practices). + * [Preventing cross-site scripting (XSS)](#xss). + * [Trusting safe values](#bypass-security-apis). + * [HTTP-Level vulnerabilities](#http). + * [Auditing Angular applications](#code-review). :marked You can run the in Plunker and download the code from there. @@ -108,14 +107,13 @@ h2#xss Preventing cross-site scripting (XSS) +makeExcerpt('src/app/inner-html-binding.component.ts', 'class') -block html-sanitization - :marked - Angular recognizes the value as unsafe and automatically sanitizes it, which removes the `