From 30cc9cfd35b94716b1de5e182b09df1a86c389a7 Mon Sep 17 00:00:00 2001 From: Jules Kremer Date: Wed, 1 Mar 2017 14:40:27 -0800 Subject: [PATCH] Revert "Revert "docs(Guide): Content edits in the Angular 2 Guide. (#3159)"" This reverts commit b97fa49eeaef7dfcbca9a1be45e138b95d30f2bb. We are trying to revert his via github UI and reopen the original PR --- public/docs/ts/latest/glossary.jade | 283 +++++++++-------- public/docs/ts/latest/guide/forms.jade | 407 ++++++++++++------------- 2 files changed, 355 insertions(+), 335 deletions(-) diff --git a/public/docs/ts/latest/glossary.jade b/public/docs/ts/latest/glossary.jade index 8f07095f65..dcc72bcd1f 100644 --- a/public/docs/ts/latest/glossary.jade +++ b/public/docs/ts/latest/glossary.jade @@ -9,13 +9,14 @@ block includes - var _decoratorLink = '' + _decorator + '' :marked - Angular has a vocabulary of its own. - Most Angular terms are everyday English words + Angular has its own vocabulary. + Most Angular terms are common English words with a specific meaning within the Angular system. This glossary lists the most prominent terms and a few less familiar ones that have unusual or unexpected definitions. + [A](#A) [B](#B) [C](#C) [D](#D) [E](#E) [F](#F) [G](#G) [H](#H) [I](#I) [J](#J) [K](#K) [L](#L) [M](#M) [N](#N) [O](#O) [P](#P) [Q](#Q) [R](#R) @@ -28,7 +29,7 @@ a#aot ## Ahead-of-time (AOT) compilation .l-sub-section :marked - You can compile Angular applications at build-time. + You can compile Angular applications at build time. By compiling your application using the compiler-cli, `ngc`, you can bootstrap directly to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle. Ahead-of-time compiled applications also benefit from decreased load time and increased performance. @@ -41,10 +42,10 @@ a#aot 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 + 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 Module](!{docsLatest}/guide/ngmodule.html) page. + For details and examples, see the [Angular Modules (NgModule)](!{docsLatest}/guide/ngmodule.html) page. +ifDocsFor('ts|dart') :marked @@ -64,7 +65,7 @@ a#attribute-directives other HTML elements, attributes, properties, and components. They are usually represented as HTML attributes, hence the name. - A good example of an attribute directive is the `ngClass` directive for adding and removing CSS class names. + 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. @@ -75,10 +76,10 @@ a#attribute-directives ## Barrel .l-sub-section :marked - A barrel is a way to *rollup exports* from several ES2015 modules into a single convenient ES2015 module. + 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. - Imagine three ES2015 modules in a `heroes` folder: + For example, imagine three ES2015 modules in a `heroes` folder: code-example. // heroes/hero.component.ts export class HeroComponent {} @@ -89,7 +90,7 @@ a#attribute-directives // heroes/hero.service.ts export class HeroService {} :marked - Without a barrel, a consumer would need three import statements: + 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'; @@ -109,18 +110,18 @@ a#attribute-directives .alert.is-important :marked - Note that you can often achieve this using [Angular modules](#angular-module) instead. + You can often achieve the same result using [Angular modules](#angular-module) instead. :marked ## Binding .l-sub-section :marked - Almost always refers to [Data Binding](#data-binding) and the act of + Usually refers to [data binding](#data-binding) and the act of binding an HTML object property to a data object property. - May refer to a [dependency injection](#dependency-injection) binding - between a "token", also referred to as a "key", and a dependency [provider](#provider). - This more rare usage should be clear in context. + Sometimes refers to a [dependency-injection](#dependency-injection) binding + between a "token"—also referred to as a "key"—and a dependency [provider](#provider). + When using this more rare usage, be clear in context. :marked ## Bootstrap @@ -130,7 +131,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. :marked - You can bootstrap multiple apps in the same `index.html`, each with its own top level root. + You can bootstrap multiple apps in the same `index.html`, each app with its own top-level root. .l-main-section#C :marked @@ -140,10 +141,10 @@ a#attribute-directives The practice of writing compound words or phrases such that each word or abbreviation begins with a capital letter _except the first letter, which is lowercase_. - Function, property, and method names are typically spelled in camelCase. Examples include: `square`, `firstName` and `getHeroes`. Notice that `square` is an example of how you write a single word in camelCase. + Function, property, and method names are typically spelled in camelCase. For example, `square`, `firstName`, and `getHeroes`. Notice that `square` is an example of how you write a single word in camelCase. - This form is also known as **lower camel case**, to distinguish it from **upper camel case**, which is [PascalCase](#pascalcase). - When you see "camelCase" in this documentation it always means *lower camel case*. + camelCase is also known as *lower camel case* to distinguish it from *upper camel case*, or [PascalCase](#pascalcase). + In Angular documentation, "camelCase" always means *lower camel case*. a#component :marked @@ -155,9 +156,9 @@ 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). - You apply the `!{_at}Component` !{_decoratorLink} to + Apply the `!{_at}Component` !{_decoratorLink} to the component class, thereby attaching to the class the essential component metadata - that Angular needs to create a component instance and render it with its template + that Angular needs to create a component instance and render the component with its template as a view. Those familiar with "MVC" and "MVVM" patterns will recognize @@ -169,7 +170,7 @@ a#component .l-sub-section :marked 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](#kebab-case). + 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 @@ -180,17 +181,18 @@ a#component .l-sub-section :marked Applications display data values to a user and respond to user - actions (clicks, touches, keystrokes). - - Instead of manually pushing application data values into HTML, attaching + actions (such as clicks, touches, and keystrokes). + + In data binding, you declare the relationship between an HTML widget and data source + and let the framework handle the details. + Data binding is an alternative to manually pushing application data values into HTML, attaching event listeners, pulling changed values from the screen, and - updating application data values, you can use data binding by declaring the relationship between an HTML widget and data source and let the - framework handle the details. + updating application data values. - Angular has a rich data binding framework with a variety of data binding + Angular has a rich data-binding framework with a variety of data-binding operations and supporting declaration syntax. - Read about the forms of binding in the [Template Syntax](!{docsLatest}/guide/template-syntax.html) page: + 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). @@ -208,14 +210,14 @@ a#component .l-sub-section block decorator-defn :marked - A decorator is a **function** that adds metadata to a class, its members (properties, methods) and function arguments. + A *function* that adds metadata to a class, its members (properties, methods) and function arguments. - Decorators are a JavaScript language [feature](https://github.com/wycats/javascript-decorators), implemented in TypeScript and proposed for ES2016 (AKA ES7). + Decorators are a JavaScript language [feature](https://github.com/wycats/javascript-decorators), implemented in TypeScript and proposed for ES2016 (also known as ES7). - To apply a decorator, position it immediately above or to the left of the thing it decorates. + To apply a decorator, position it immediately above or to the left of the item it decorates. Angular has its own set of decorators to help it interoperate with your application parts. - Here is an example of a `@Component` decorator that identifies a + The following example is a `@Component` decorator that identifies a class as an Angular [component](#component) and an `@Input` decorator applied to the `name` property of that component. The elided object argument to the `@Component` decorator would contain the pertinent component metadata. ``` @@ -227,7 +229,7 @@ a#component ``` The scope of a decorator is limited to the language feature that it decorates. None of the decorations shown here will "leak" to other - classes appearing below it in the file. + classes that follow it in the file. .alert.is-important :marked @@ -237,7 +239,10 @@ a#component ## Dependency injection .l-sub-section :marked - Dependency injection is both a design pattern and a mechanism + + + A design pattern and mechanism for creating and delivering parts of an application to other parts of an application that request them. @@ -246,23 +251,26 @@ a#component These parts often rely on other parts. An Angular [component](#component) part might rely on a service part to get data or perform a calculation. When - part "A" relies on another part "B", you say that "A" depends on "B" and - that "B" is a dependency of "A". + part "A" relies on another part "B," you say that "A" depends on "B" and + that "B" is a dependency of "A." You can ask a "dependency injection system" to create "A" - and it will handle all of "A"s dependencies. - If "A" needs "B" and "B" needs "C", the system resolves that chain of dependencies - and returns a fully prepared instance of "A". + for us and handle all the dependencies. + If "A" needs "B" and "B" needs "C," the system resolves that chain of dependencies + and returns a fully prepared instance of "A." + Angular provides and relies upon its own sophisticated - [dependency injection](!{docsLatest}/guide/dependency-injection.html) system + dependency-injection system to assemble and run applications by "injecting" application parts into other application parts where and when needed. - At the core there is an [`injector`](#injector) that returns dependency values on request. + At the core, an [`injector`](#injector) returns dependency values on request. The expression `injector.get(token)` returns the value associated with the given token. + - A token is an Angular type (`OpaqueToken`). You rarely deal with tokens directly; most + A token is an Angular type (`OpaqueToken`). You rarely need to work with tokens directly; most methods accept a class name (`Foo`) or a string ("foo") and Angular converts it to a token. When you write `injector.get(Foo)`, the injector returns the value associated with the token for the `Foo` class, typically an instance of `Foo` itself. @@ -292,9 +300,11 @@ a#directives .l-sub-section :marked An Angular class responsible for creating, reshaping, and interacting with HTML elements - in the browser DOM. Directives are Angular's most fundamental feature. + in the browser DOM. The directive is Angular's most fundamental feature. + + A directive is ususally associated with an HTML element or attribute. + This element or attribute is often referred to as the directive itself. - A directive is almost always associated with an HTML element or attribute. When Angular finds a directive in an HTML template, it creates the matching directive class instance and gives the instance control over that portion of the browser DOM. @@ -304,19 +314,21 @@ a#directives as if you were writing native HTML. In this way, directives become extensions of HTML itself. - Directives fall into three categories: - 1. [Components](#component) that combine application logic with an HTML template to + Directives fall into one of the following categories: + + * [Components](#component) combine application logic with an HTML template to render application [views](#view). Components are usually represented as HTML elements. - They are the building blocks of an Angular application and the - developer can expect to write a lot of them. + They are the building blocks of an Angular application. - 1. [Attribute directives](#attribute-directive) that can listen to and modify the behavior of - HTML elements, components, and other directives. They are usually represented + 1. [Attribute directives](#attribute-directive) can listen to and modify the behavior of + other HTML elements, attributes, properties, and components. They are usually represented as HTML attributes, hence the name. - 1. [Structural directives](#structural-directive) that - shape or reshape HTML layout, typically by adding and removing elements in the DOM. + 1. [Structural directives](#structural-directive) are responsible for + shaping or reshaping HTML layout, typically by adding, removing, or manipulating + elements and their children. + .l-main-section#E @@ -328,32 +340,31 @@ a#directives The latest approved version of JavaScript is [ECMAScript 2016](http://www.ecma-international.org/ecma-262/7.0/) - (AKA "ES2016" or "ES7") and many Angular developers write their applications - either in this version of the language or a dialect that strives to be + (also known as "ES2016" or "ES7"). Many Angular developers write their applications + in ES7 or a dialect that strives to be compatible with it, such as [TypeScript](#typescript). - Most modern browsers today only support the much older "ECMAScript 5" (AKA ES5) standard. - Applications written in ES2016, ES2015 or one of their dialects must be "[transpiled](#transpile)" + Most modern browsers only support the much older "ECMAScript 5" (also known as "ES5") standard. + Applications written in ES2016, ES2015, or one of their dialects must be [transpiled](#transpile) to ES5 JavaScript. - Angular developers may choose to write in ES5 directly. + Angular developers can write in ES5 directly. :marked ## ES2015 .l-sub-section :marked Short hand for [ECMAScript](#ecmascript) 2015. -:marked - ## ES6 -.l-sub-section - :marked - Short hand for [ECMAScript](#ecmascript) 2015. :marked ## ES5 .l-sub-section :marked Short hand for [ECMAScript](#ecmascript) 5, the version of JavaScript run by most modern browsers. - See [ECMAScript](#ecmascript). +:marked + ## ES6 +.l-sub-section + :marked + Short hand for [ECMAScript](#ecmascript) 2015. a#F a#G @@ -363,15 +374,15 @@ a#H ## Injector .l-sub-section :marked - An object in the Angular [dependency injection system](#dependency-injection) - that can find a named "dependency" in its cache or create such a thing + An object in the Angular [dependency-injection system](#dependency-injection) + that can find a named dependency in its cache or create a dependency with a registered [provider](#provider). :marked ## Input .l-sub-section :marked - A directive property that can be the ***target*** of a + 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). Data values flow *into* this property from the data source identified in the template expression to the right of the equal sign. @@ -402,8 +413,8 @@ a#jit ## Just-in-time (JIT) compilation .l-sub-section :marked - With Angular _just-in-time_ bootstrapping you compile your components and modules in the browser - and launch the application dynamically. This is a good choice during development. + 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. .l-main-section#K @@ -428,14 +439,14 @@ a#jit For example, the `OnInit` interface has a hook method named `ngOnInit`. Angular calls these hook methods in the following order: - * `ngOnChanges` - when an [input](#input)/[output](#output) binding value changes. - * `ngOnInit` - after the first `ngOnChanges`. - * `ngDoCheck` - developer's custom change detection. - * `ngAfterContentInit` - after component content initialized. - * `ngAfterContentChecked` - after every check of component content. - * `ngAfterViewInit` - after component's view(s) are initialized. - * `ngAfterViewChecked` - after every check of a component's view(s). - * `ngOnDestroy` - just before the directive is destroyed. + * `ngOnChanges`: when an [input](#input)/[output](#output) binding value changes. + * `ngOnInit`: after the first `ngOnChanges`. + * `ngDoCheck`: developer's custom change detection. + * `ngAfterContentInit`: after component content initialized. + * `ngAfterContentChecked`: after every check of component content. + * `ngAfterViewInit`: after a component's views are initialized. + * `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. @@ -447,35 +458,36 @@ a#jit block module-defn .alert.is-important :marked - In Angular, there are two types of modules: + Angular has the following types of modules: - [Angular modules](#angular-module). For details and examples, see the [Angular Modules](!{docsLatest}/guide/ngmodule.html) page. - ES2015 modules, as described in this section. :marked + A cohesive block of code dedicated to a single purpose. + Angular apps are modular. - In general, you assemble your application from many modules, both the ones you write and the ones you acquire from others. - - A typical module is a cohesive block of code dedicated to a single purpose. - - A module **exports** something of value in that code, typically one thing such as a class. - A module that needs that thing, **imports** it. + In general, you assemble an application from many modules, both the ones you write and the ones you acquire from others. + + A module *exports* something of value in that code, typically one thing such as a class. + A module that needs that thing *imports* it. + The structure of Angular modules and the import/export syntax is based on the [ES2015 module standard](http://www.2ality.com/2014/09/es6-modules-final.html). An application that adheres to this standard requires a module loader to - load modules on request, and resolve inter-module dependencies. - Angular does not ship with a module loader and does not have a preference - for any particular 3rd party library (although most examples use SystemJS). - You may pick any module library that conforms to the standard. + load modules on request and resolve inter-module dependencies. + Angular doesn't include a module loader and doesn't have a preference + for any particular third-party library (although most examples use SystemJS). + You can use any module library that conforms to the standard. Modules are typically named after the file in which the exported thing is defined. The Angular [DatePipe](https://github.com/angular/angular/blob/master/modules/@angular/common/src/pipes/date_pipe.ts) class belongs to a feature module named `date_pipe` in the file `date_pipe.ts`. - You rarely access Angular feature modules directly. You usually import them from one of the Angular [scoped packages](#scoped-package) such as `@angular/core`. + You rarely access Angular feature modules directly. You usually import them from an Angular [scoped package](#scoped-package) such as `@angular/core`. a#N .l-main-section#O @@ -485,19 +497,20 @@ a#N ## Observable .l-sub-section :marked - You can think of an observable as an array whose items arrive asynchronously over time. + 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 ES 2016, the next version of JavaScript. + 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](!{docsLatest}/guide/template-syntax.html#event-binding). + 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). Events stream *out* of this property to the receiver identified in the template expression to the right of the equal sign. @@ -509,14 +522,17 @@ a#N ## PascalCase .l-sub-section :marked - The practice of writing individual words, compound words, or phrases such that each word or abbreviation begins with a capital letter. Class names are typically spelled in PascalCase. Examples include: `Person` and `HeroDetailComponent`. + The practice of writing individual words, compound words, or phrases such that each word or abbreviation begins with a capital letter. + Class names are typically spelled in PascalCase. For example, `Person` and `HeroDetailComponent`. - This form is also known as **upper camel case** to distinguish it from **lower camel case**, which is simply called [camelCase](#camelcase). In this documentation, "PascalCase" means *upper camel case* and "camelCase" means *lower camel case*. + This form is also known as *upper camel case* to distinguish it from *lower camel case* or simply [camelCase](#camelcase). + In this documentation, "PascalCase" means *upper camel case* and "camelCase" means *lower camel case*. :marked ## Pipe .l-sub-section :marked + An Angular pipe is a function that transforms input values to output values for display in a [view](#view). Here's an example that uses the built-in `currency` pipe to display @@ -526,6 +542,7 @@ a#N {{product.price | currency}} :marked + You can also write your own custom pipes. Read more in the page on [pipes](!{docsLatest}/guide/pipes.html). @@ -546,15 +563,15 @@ a#Q .l-sub-section :marked A technique for building Angular forms through code in a component. - The alternate technique is [Template-Driven Forms](#template-driven-forms). + The alternative technique is [template-driven forms](#template-driven-forms). When building reactive forms: - The "source of truth" is the component. The validation is defined using code in the component. - Each control is explicitly created in the component class with `new FormControl()` or with `FormBuilder`. - The template input elements do *not* use `ngModel`. - - The associated Angular directives are all prefixed with `Form` such as `FormGroup`, `FormControl`, and `FormControlName`. + - The associated Angular directives are all prefixed with `Form`, such as `FormGroup`, `FormControl`, and `FormControlName`. - Reactive forms are powerful, flexible, and great for more complex data entry form scenarios such as dynamic generation of form controls. + Reactive forms are powerful, flexible, and a good choice for more complex data-entry form scenarios, such as dynamic generation of form controls. :marked ## Router @@ -565,11 +582,11 @@ a#Q and performing other similar actions that cause the application to replace one view with another. - The Angular [component router](!{docsLatest}/guide/router.html) is a richly featured mechanism for configuring and managing the entire view navigation process including the creation and destruction + The Angular component router 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](#router) by means + 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 @@ -604,31 +621,23 @@ a#Q ## Scoped package .l-sub-section :marked - Angular modules are delivered within *scoped packages* such as `@angular/core`, `@angular/common`, `@angular/platform-browser-dynamic`, - `@angular/http`, and `@angular/router`. + A way to group related *npm* packages. + Read more at the [npm-scope](https://docs.npmjs.com/misc/scope) page. - A [*scoped package*](https://docs.npmjs.com/misc/scope) is a way to group related *npm* packages. + Angular modules are delivered within *scoped packages* such as `@angular/core`, + `@angular/common`, `@angular/platform-browser-dynamic`, `@angular/http`, and `@angular/router`. - You import a scoped package the same way that you'd import a *normal* package. + Import a scoped package the same way that you import a normal package. The only difference, from a consumer perspective, - is that the *scoped package* name begins with the Angular *scope name*, `@angular`. + is that the scoped package name begins with the Angular *scope name*, `@angular`. +makeExcerpt('architecture/ts/src/app/app.component.ts', 'import', '') -a#snake-case -:marked - ## snake_case - -.l-sub-section - block snake-case-defn - :marked - The practice of writing compound words or phrases such that an - underscore (`_`) separates one word from the next. This form is also known as **underscore case**. - :marked ## Service .l-sub-section :marked + For data or logic that is not associated with a specific view or that you want to share across components, build services. @@ -639,10 +648,23 @@ a#snake-case independent from any specific view, provide shared data or logic across components, or encapsulate external interactions. + 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. +a#snake-case +:marked + ## snake_case + +.l-sub-section + block snake-case-defn + :marked + The practice of writing compound words or phrases such that an + underscore (`_`) separates one word from the next. This form is also known as *underscore case*. + a#structural-directive a#structural-directives + :marked ## Structural directives .l-sub-section @@ -658,8 +680,8 @@ a#structural-directives ## Template .l-sub-section :marked - A template is a chunk of HTML that Angular uses to render a [view](#view) with - the support and continuing guidance of an Angular [directive](#directive), + A chunk of HTML that Angular uses to render a [view](#view) with + the support and guidance of an Angular [directive](#directive), most notably a [component](#component). @@ -673,11 +695,11 @@ a#structural-directives When building template-driven forms: - The "source of truth" is the template. The validation is defined using attributes on the individual input elements. - - [Two-way binding](#data-binding) with `ngModel` keeps the component model in synchronization with the user's entry into the input elements. + - [Two-way binding](#data-binding) with `ngModel` keeps the component model synchronized with the user's entry into the input elements. - Behind the scenes, Angular creates a new control for each input element, provided you have set up a `name` attribute and two-way binding for each input. - The associated Angular directives are all prefixed with `ng` such as `ngForm`, `ngModel`, and `ngModelGroup`. - Template-driven forms are convenient, quick, and simple. They are a good choice for many basic data entry form scenarios. + Template-driven forms are convenient, quick, and simple. They are a good choice for many basic data-entry form scenarios. Read about how to build template-driven forms in the [Forms](!{docsLatest}/guide/forms.html) page. @@ -686,18 +708,19 @@ a#structural-directives ## Template expression .l-sub-section :marked - An expression is a !{_Lang}-like syntax that Angular evaluates within + A !{_Lang}-like syntax that Angular evaluates within a [data binding](#data-binding). Read about how to write template expressions - in the [Template Syntax](!{docsLatest}/guide/template-syntax.html#template-expressions) page. + in the [Template expressions](!{docsLatest}/guide/template-syntax.html#template-expressions) section + of the [Template Syntax](!{docsLatest}/guide/template-syntax.html#) page. :marked ## Transpile .l-sub-section :marked The process of transforming code written in one form of JavaScript - (for example, TypeScript) into another form of JavaScript (for example, [ES5](#es5)). + (such as TypeScript) into another form of JavaScript (such as [ES5](#es5)). :marked ## TypeScript @@ -706,15 +729,15 @@ a#structural-directives A version of JavaScript that supports most [ECMAScript 2015](#es2015) language features such as [decorators](#decorator). - TypeScript is also noteable for its optional typing system, which enables - compile-time type checking and strong tooling support (for example, "intellisense", + TypeScript is also notable for its optional typing system, which provides + compile-time type checking and strong tooling support (such as "intellisense," code completion, refactoring, and intelligent search). Many code editors and IDEs support TypeScript either natively or with plugins. - TypeScript is the preferred language for Angular development although + TypeScript is the preferred language for Angular development, although you can use other JavaScript dialects such as [ES5](#es5). - Read more about TypeScript at [typescript.org](http://www.typescriptlang.org/). + Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/). a#U .l-main-section#V @@ -723,7 +746,7 @@ a#U ## View .l-sub-section :marked - A view is a portion of the screen that displays information and responds + A portion of the screen that displays information and responds to user actions such as clicks, mouse moves, and keystrokes. Angular renders a view under the control of one or more [directives](#directive), @@ -731,7 +754,7 @@ a#U The component plays such a prominent role that it's often convenient to refer to a component as a view. - Views often contain other views and any view might be loaded and unloaded + Views often contain other views. Any view might be loaded and unloaded dynamically as the user navigates through the application, typically under the control of a [router](#router). @@ -745,11 +768,11 @@ a#Y .l-sub-section block zone-defn :marked - Zones are a mechanism for encapsulating and intercepting + A mechanism for encapsulating and intercepting a JavaScript application's asynchronous activity. The browser DOM and JavaScript have a limited number - of asynchronous activities, activities such as DOM events (for example, clicks), + of asynchronous activities, such as DOM events (for example, clicks), [promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), and [XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) calls to remote servers. @@ -758,7 +781,7 @@ a#Y to take action before and after the async activity finishes. Angular runs your application in a zone where it can respond to - asynchronous events by checking for data changes, and updating + asynchronous events by checking for data changes and updating the information it displays via [data bindings](#data-binding). Learn more about zones in this diff --git a/public/docs/ts/latest/guide/forms.jade b/public/docs/ts/latest/guide/forms.jade index 1c36b14f13..977cef4cc8 100644 --- a/public/docs/ts/latest/guide/forms.jade +++ b/public/docs/ts/latest/guide/forms.jade @@ -1,84 +1,83 @@ include ../_util-fns :marked - We’ve all used a form to log in, submit a help request, place an order, book a flight, - schedule a meeting, and perform countless other data entry tasks. Forms are the mainstay of business applications. + You use forms to log in, submit a help request, place an order, book a flight, + schedule a meeting, and perform countless other data-entry tasks. - Any seasoned web developer can slap together an HTML form with all the right tags. - It's more challenging to create a cohesive data entry experience that guides the - user efficiently and effectively through the workflow behind the form. + In developing a form, it's important to create a data-entry experience that guides the + user efficiently and effectively through the workflow. - *That* takes design skills that are, to be frank, well out of scope for this guide. + Developing forms requires design skills (which are out of scope for this page), as well as framework support for + *two-way data binding, change tracking, validation, and error handling*, + which you'll learn about on this page. - It also takes framework support for - **two-way data binding, change tracking, validation, and error handling** - ... which we shall cover in this guide on Angular forms. + This page shows you how to build a simple form from scratch. Along the way you'll learn how to: - We will build a simple form from scratch, one step at a time. Along the way we'll learn how to: + - Build an Angular form with a component and template. + - Use `ngModel` to create two-way data bindings for reading and writing input-control values. + - Track state changes and the validity of form controls. + - Provide visual feedback using special CSS classes that track the state of the controls. + - Display validation errors to users and enable/disable form controls. + - Share information across HTML elements using template reference variables. - - Build an Angular form with a component and template - - Use `ngModel` to create two-way data bindings for reading and writing input control values - - Track state changes and the validity of form controls - - Provide visual feedback using special CSS classes that track the state of the controls - - Display validation errors to users and enable/disable form controls - - Share information across HTML elements using template reference variables - - Run the . + You can run the in Plunker and download the code from there. .l-main-section#template-driven :marked ## Template-driven forms - Many of us will build forms by writing templates in the Angular [template syntax](./template-syntax.html) with - the form-specific directives and techniques described in this guide. - + You can build forms by writing templates in the Angular [template syntax](./template-syntax.html) with + the form-specific directives and techniques described in this page. + .l-sub-section :marked - That's not the only way to create a form but it's the way we'll cover in this guide. + You can also use a reactive (or model-driven) approach to build forms. + However, this page focuses on template-driven forms. + :marked - We can build almost any form we need with an Angular template — login forms, contact forms, pretty much any business form. - We can lay out the controls creatively, bind them to data, specify validation rules and display validation errors, + You can build almost any form with an Angular template—login forms, contact forms, and pretty much any business form. + You can lay out the controls creatively, bind them to data, specify validation rules and display validation errors, conditionally enable or disable specific controls, trigger built-in visual feedback, and much more. - It will be pretty easy because Angular handles many of the repetitive, boilerplate tasks we'd - otherwise wrestle with ourselves. + Angular makes the process easy by handling many of the repetitive, boilerplate tasks you'd + otherwise wrestle with yourself. - We'll discuss and learn to build a template-driven form that looks like this: + You'll learn to build a template-driven form that looks like this: figure.image-display img(src="/resources/images/devguide/forms/hero-form-1.png" width="400px" alt="Clean Form") :marked - Here at the *Hero Employment Agency* we use this form to maintain personal information about heroes. - Every hero needs a job. It's our company mission to match the right hero with the right crisis! + The *Hero Employment Agency* uses this form to maintain personal information about heroes. + Every hero needs a job. It's the company mission to match the right hero with the right crisis. Two of the three fields on this form are required. Required fields have a green bar on the left to make them easy to spot. - If we delete the hero name, the form displays a validation error in an attention-grabbing style: + If you delete the hero name, the form displays a validation error in an attention-grabbing style: figure.image-display img(src="/resources/images/devguide/forms/hero-form-2.png" width="400px" alt="Invalid, Name Required") :marked - Note that the submit button is disabled, and the "required" bar to the left of the input control changed from green to red. + Note that the *Submit* button is disabled, and the "required" bar to the left of the input control changes from green to red. .l-sub-section :marked - We'll customize the colors and location of the "required" bar with standard CSS. + You can customize the colors and location of the "required" bar with standard CSS. :marked - We'll build this form in small steps: + You'll build this form in small steps: 1. Create the `Hero` model class. 1. Create the component that controls the form. 1. Create a template with the initial form layout. - 1. Bind data properties to each form control using the `ngModel` two-way data binding syntax. - 1. Add a `name` attribute to each form input control. + 1. Bind data properties to each form control using the `ngModel` two-way data-binding syntax. + 1. Add a `name` attribute to each form-input control. 1. Add custom CSS to provide visual feedback. - 1. Show and hide validation error messages. - 1. Handle form submission with **ngSubmit**. - 1. Disable the form’s submit button until the form is valid. + 1. Show and hide validation-error messages. + 1. Handle form submission with *ngSubmit*. + 1. Disable the form’s *Submit* button until the form is valid. :marked ## Setup @@ -88,11 +87,11 @@ figure.image-display ## Create the Hero model class - As users enter form data, we'll capture their changes and update an instance of a model. - We can't lay out the form until we know what the model looks like. + As users enter form data, you'll capture their changes and update an instance of a model. + You can't lay out the form until you know what the model looks like. A model can be as simple as a "property bag" that holds facts about a thing of application importance. - That describes well our `Hero` class with its three required fields (`id`, `name`, `power`) + 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: @@ -100,14 +99,14 @@ figure.image-display +makeExample('src/app/hero.ts') :marked - It's an anemic model with few requirements and no behavior. Perfect for our demo. + It's an anemic model with few requirements and no behavior. Perfect for the demo. The TypeScript compiler generates a public field for each `public` constructor parameter and - assigns the parameter’s value to that field automatically when we create new heroes. + automatically assigns the parameter’s value to that field when you create heroes. - The `alterEgo` is optional, so the constructor lets us omit it; note the (?) in `alterEgo?`. + The `alterEgo` is optional, so the constructor lets you omit it; note the question mark (?) in `alterEgo?`. - We can create a new hero like this: + You can create a new hero like this: +makeExcerpt('src/app/hero-form.component.ts', 'SkyDog', '') @@ -117,7 +116,7 @@ figure.image-display An Angular form has two parts: an HTML-based _template_ and a component _class_ to handle data and user interactions programmatically. - We begin with the class because it states, in brief, what the hero editor can do. + Begin with the class because it states, in brief, what the hero editor can do. Create the following file with the given content: @@ -125,45 +124,45 @@ figure.image-display :marked There’s nothing special about this component, nothing form-specific, - nothing to distinguish it from any component we've written before. + nothing to distinguish it from any component you've written before. - Understanding this component requires only the Angular concepts covered in previous guides. + Understanding this component requires only the Angular concepts covered in previous pages. - 1. The code imports the Angular core library, and the `Hero` model we just created. - 1. The `@Component` selector value of "hero-form" means we can drop this form in a parent template with a `` tag. - 1. The `moduleId: module.id` property sets the base for module-relative loading of the `templateUrl`. - 1. The `templateUrl` property points to a separate file for the template HTML. - 1. We defined dummy data for `model` and `powers`, as befits a demo. - Down the road, we can inject a data service to get and save real data - or perhaps expose these properties as - [inputs and outputs](./template-syntax.html#inputs-outputs) for binding to a - parent component. None of this concerns us now and these future changes won't affect our form. - 1. We threw in a `diagnostic` property to return a JSON representation of our model. - It'll help us see what we're doing during our development; we've left ourselves a cleanup note to discard it later. + - The code imports the Angular core library and the `Hero` model you just created. + - The `@Component` selector value of "hero-form" means you can drop this form in a parent template with a `` tag. + - The `moduleId: module.id` property sets the base for module-relative loading of the `templateUrl`. + - The `templateUrl` property points to a separate file for the template HTML. + - You defined dummy data for `model` and `powers`, as befits a demo. + Down the road, you can inject a data service to get and save real data + or perhaps expose these properties as inputs and outputs + (see [Input and output properties](./template-syntax.html#inputs-outputs) on the + [Template Syntax](./template-syntax.html) page) for binding to a + parent component. This is not a concern now and these future changes won't affect the form. + - You added a `diagnostic` property to return a JSON representation of the model. + It'll help you see what you're doing during development; you've left yourself a cleanup note to discard it later. ### Why the separate template file? - Why don't we write the template inline in the component file as we often do elsewhere? + Why don't you write the template inline in the component file as you often do elsewhere? - There is no “right” answer for all occasions. We like inline templates when they are short. - Most form templates won't be short. TypeScript and JavaScript files generally aren't the best place to - write (or read) large stretches of HTML and few editors are much help with files that have a mix of HTML and code. - We also like short files with a clear and obvious purpose like this one. + There is no "right" answer for all occasions. Inline templates are useful when they are short. + Most form templates aren't short. TypeScript and JavaScript files generally aren't the best place to + write (or read) large stretches of HTML, and few editors help with files that have a mix of HTML and code. - Form templates tend to be quite large even when displaying a small number of fields + Form templates tend to be large, even when displaying a small number of fields, so it's usually best to put the HTML template in a separate file. - We'll write that template file in a moment. Before we do, we'll take a step back - and revise the `app.module.ts` and `app.component.ts` to make use of the new `HeroFormComponent`. + You'll write that template file in a moment. First, + revise the `app.module.ts` and `app.component.ts` to make use of the new `HeroFormComponent`. .l-main-section :marked ## Revise *app.module.ts* - `app.module.ts` defines the application's root module. In it we identify the external modules we'll use in our application - and declare the components that belong to this module, such as our `HeroFormComponent`. + `app.module.ts` defines the application's root module. In it you identify the external modules you'll use in the application + and declare the components that belong to this module, such as the `HeroFormComponent`. - Because template-driven forms are in their own module, we need to add the `FormsModule` to the array of - `imports` for our application module before we can use forms. + Because template-driven forms are in their own module, you need to add the `FormsModule` to the array of + `imports` for the application module before you can use forms. Replace the contents of the "QuickStart" version with the following: +makeExample('forms/ts/src/app/app.module.ts', null, 'src/app/app.module.ts') @@ -173,24 +172,26 @@ figure.image-display :marked There are three changes: - 1. We import `FormsModule` and our new `HeroFormComponent`. + 1. You import `FormsModule` and the new `HeroFormComponent`. - 1. We add the `FormsModule` to the list of `imports` defined in the `ngModule` decorator. This gives our application + 1. You add the `FormsModule` to the list of `imports` defined in the `ngModule` decorator. This gives the application access to all of the template-driven forms features, including `ngModel`. - 1. We add the `HeroFormComponent` to the list of `declarations` defined in the `ngModule` decorator. This makes + 1. You add the `HeroFormComponent` to the list of `declarations` defined in the `ngModule` decorator. This makes the `HeroFormComponent` component visible throughout this module. .alert.is-important :marked - If a component, directive, or pipe belongs to a module in the `imports` array, ​_DON'T_​ re-declare it in the `declarations` array. - If you wrote it and it should belong to this module, ​_DO_​ declare it in the `declarations` array. + If a component, directive, or pipe belongs to a module in the `imports` array, ​_don't_​ re-declare it in the `declarations` array. + If you wrote it and it should belong to this module, ​_do_​ declare it in the `declarations` array. +// CF: Not sure I understand what "If you wrote it" means. Does it matter who wrote it? + What if someone else wrote the component but it should belong to this module? Should I declare it or not? .l-main-section :marked ## Revise *app.component.ts* - `AppComponent` is the application's root component. It will host our new `HeroFormComponent`. + `AppComponent` is the application's root component. It will host the new `HeroFormComponent`. Replace the contents of the "QuickStart" version with the following: @@ -201,40 +202,40 @@ figure.image-display :marked There are only two changes. The `template` is simply the new element tag identified by the component's `selector` property. - This will display the hero form when the application component is loaded. - We've also dropped the `name` field from the class body. + This displays the hero form when the application component is loaded. + You've also dropped the `name` field from the class body. .l-main-section :marked ## Create an initial HTML form template - Create the new template file with the following contents: + Create the template file with the following contents: +makeExample('src/app/hero-form.component.html', 'start') :marked - That is plain old HTML 5. We're presenting two of the `Hero` fields, `name` and `alterEgo`, and + The language is simply HTML5. You're presenting two of the `Hero` fields, `name` and `alterEgo`, and opening them up for user input in input boxes. The *Name* `` control has the HTML5 `required` attribute; the *Alter Ego* `` control does not because `alterEgo` is optional. - We've got a *Submit* button at the bottom with some classes on it for styling. + You added a *Submit* button at the bottom with some classes on it for styling. - **We are not using Angular yet**. There are no bindings, no extra directives, just layout. + *You're not using Angular yet*. There are no bindings or extra directives, just layout. The `container`, `form-group`, `form-control`, and `btn` classes - come from [Twitter Bootstrap](http://getbootstrap.com/css/). Purely cosmetic. - We're using Bootstrap to give the form a little style! + come from [Twitter Bootstrap](http://getbootstrap.com/css/). These classes are purely cosmetic. + Bootstrap gives the form a little style. .callout.is-important - header Angular forms do not require a style library + header Angular forms don't require a style library :marked Angular makes no use of the `container`, `form-group`, `form-control`, and `btn` classes or - the styles of any external library. Angular apps can use any CSS library, or none at all. + the styles of any external library. Angular apps can use any CSS library or none at all. :marked - Let's add the stylesheet. Open `index.html` and add the following link to the ``: + To add the stylesheet, open `index.html` and add the following link to the ``: +makeExcerpt('src/index.html', 'bootstrap') @@ -242,12 +243,12 @@ figure.image-display :marked ## Add powers with _*ngFor_ - Our hero must choose one super power from a fixed list of Agency-approved powers. - We maintain that list internally (in `HeroFormComponent`). + The hero must choose one superpower from a fixed list of agency-approved powers. + You maintain that list internally (in `HeroFormComponent`). - We'll add a `select` to our + You'll add a `select` to the form and bind the options to the `powers` list using `ngFor`, - a technique seen previously in the [Displaying Data](./displaying-data.html) guide. + a technique seen previously in the [Displaying Data](./displaying-data.html) page. Add the following HTML *immediately below* the *Alter Ego* group: @@ -256,7 +257,7 @@ figure.image-display :marked This code repeats the `