diff --git a/aio/content/guide/animations.md b/aio/content/guide/animations.md index 4f48dae2ce..1928446ae0 100644 --- a/aio/content/guide/animations.md +++ b/aio/content/guide/animations.md @@ -66,7 +66,7 @@ The examples in this page are available as a . ## Quickstart example: Transitioning between two states
- A simple transition animation + A simple transition animation
@@ -172,7 +172,7 @@ controls the timing of switching between one set of styles and the next:
- In Angular animations you define states and transitions between states + In Angular animations you define states and transitions between states
@@ -220,7 +220,7 @@ transitions that apply regardless of which state the animation is in. For exampl
- The wildcard state can be used to match many different transitions at once + The wildcard state can be used to match many different transitions at once
@@ -237,7 +237,7 @@ regardless of what state it was in before it left.
- The void state can be used for enter and leave transitions + The void state can be used for enter and leave transitions
@@ -247,7 +247,7 @@ The wildcard state `*` also matches `void`. ## Example: Entering and leaving
- Enter and leave animations + Enter and leave animations
@@ -258,7 +258,7 @@ entering and leaving of elements: * 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. @@ -294,7 +294,7 @@ These two common animations have their own aliases: ## Example: Entering and leaving from different states
- Enter and leave animations combined with state animations + Enter and leave animations combined with state animations
@@ -313,7 +313,7 @@ This gives you fine-grained control over each transition:
- This example transitions between active, inactive, and void states + This example transitions between active, inactive, and void states
@@ -346,7 +346,7 @@ If you don't provide a unit when specifying dimension, Angular assumes the defau ## Automatic property calculation
- Animation with automated height calculation + Animation with automated height calculation
@@ -405,7 +405,7 @@ and the delay (or as the *second* value when there is no delay):
- Animations with specific timings + Animations with specific timings
@@ -427,7 +427,7 @@ slight delay of 10 milliseconds as specified in `'0.2s 10 ease-out'`: ## Multi-step animations with keyframes
- Animations with some bounce implemented with keyframes + Animations with some bounce implemented with keyframes
@@ -461,7 +461,7 @@ offsets receive offsets `0`, `0.5`, and `1`. ## Parallel animation groups
- Parallel animations with different timings, implemented with groups + Parallel animations with different timings, implemented with groups
@@ -501,7 +501,7 @@ those callbacks like this: -The callbacks receive an `AnimationEvent` that contains contains useful properties such as +The callbacks receive an `AnimationEvent` that contains contains useful properties such as `fromState`, `toState` and `totalTime`. -Those callbacks will fire whether or not an animation is picked up. \ No newline at end of file +Those callbacks will fire whether or not an animation is picked up. diff --git a/aio/content/guide/aot-compiler.md b/aio/content/guide/aot-compiler.md index 996658dec3..a7638dcc3e 100644 --- a/aio/content/guide/aot-compiler.md +++ b/aio/content/guide/aot-compiler.md @@ -297,8 +297,8 @@ The _RxJs_ Observable library is an essential Angular dependency published as an 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 +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`: @@ -307,7 +307,7 @@ the `plugins` array in `rollup-config.js`: *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. +This cookbook relies on the _uglify_ Rollup plugin to minify and mangle the code. Add the following to the `plugins` array: @@ -317,7 +317,7 @@ Add the following to the `plugins` array: In a production setting, you would also enable gzip on the web server to compress the code into an even smaller package going over the wire. - + {@a run-rollup} @@ -602,8 +602,8 @@ showing exactly which application and Angular modules and classes are included i Here's the map for _Tour of Heroes_. - +
- toh-pt6-bundle + toh-pt6-bundle
diff --git a/aio/content/guide/architecture.md b/aio/content/guide/architecture.md index 2f8c5613c1..73a92d3f20 100644 --- a/aio/content/guide/architecture.md +++ b/aio/content/guide/architecture.md @@ -27,7 +27,7 @@ You'll learn the details in the pages that follow. For now, focus on the big pic
- overview + overview
@@ -64,23 +64,23 @@ Learn these building blocks, and you're on your way. ## Modules
- Component + Component
Angular apps are modular and Angular has its own modularity system called _Angular modules_ or _NgModules_. -_Angular modules_ are a big deal. +_Angular modules_ are a big deal. This page introduces modules; the [Angular modules](guide/ngmodule) page covers them in depth.

-Every Angular app has at least one Angular module class, [the _root module_](guide/appmodule "AppModule: the root module"), +Every Angular app has at least one Angular module class, [the _root module_](guide/appmodule "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 +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. +a workflow, or a closely related set of capabilities. An Angular module, whether a _root_ or _feature_, is a class with an `@NgModule` decorator. @@ -98,7 +98,7 @@ Learn more about decorators on the web. -`NgModule` is a decorator function that takes a single metadata object whose properties describe the module. +`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](guide/architecture#components), [directives](guide/architecture#directives), and [pipes](guide/pipes). @@ -110,7 +110,7 @@ Angular has three kinds of view classes: [components](guide/architecture#compone * `providers` - creators of [services](guide/architecture#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_, +* `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: @@ -125,15 +125,15 @@ Here's a simple root module: -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. +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. -Launch an application by _bootstrapping_ its root module. +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. - + @@ -149,7 +149,7 @@ JavaScript also has its own module system for managing collections of JavaScript 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. +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. @@ -182,12 +182,12 @@ These are two different and _complementary_ module systems. Use them both to wri
- Component + Component
-Angular ships as a collection of JavaScript modules. You can think of them as library modules. +Angular ships as a collection of JavaScript modules. You can think of them as library modules. Each Angular library name begins with the `@angular` prefix. @@ -244,7 +244,7 @@ Learn more from the [Angular modules](guide/ngmodule) page.
- Component + Component
@@ -284,7 +284,7 @@ Your app can take action at each moment in this lifecycle through optional [life ## Templates
- Template + Template
@@ -314,7 +314,7 @@ The `HeroDetailComponent` is a **child** of the `HeroListComponent`.
- Metadata + Metadata
@@ -330,7 +330,7 @@ Notice how `` rests comfortably among native HTML elements. Custom ## Metadata
- Metadata + Metadata
@@ -375,11 +375,11 @@ Angular inserts an instance of the `HeroListComponent` view between those tags. * `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. +so it can get the list of heroes to display.
- Metadata + Metadata
@@ -406,7 +406,7 @@ into actions and value updates. Writing such push/pull logic by hand is tedious, read as any experienced jQuery programmer can attest.
- Data Binding + Data Binding
@@ -454,7 +454,7 @@ from the root of the application component tree through all child components.
- Data Binding + Data Binding
@@ -463,7 +463,7 @@ Data binding plays an important role in communication between a template and its component.
- Parent/Child binding + Parent/Child binding
@@ -478,7 +478,7 @@ Data binding is also important for communication between parent and child compon ## Directives
- Parent child + Parent child
@@ -556,7 +556,7 @@ Of course, you can also write your own directives. Components such as ## Services
- Service + Service
@@ -624,7 +624,7 @@ application logic into services and make those services available to components ## Dependency injection
- Service + Service
@@ -656,7 +656,7 @@ This is *dependency injection*. The process of `HeroService` injection looks a bit like this:
- Service + Service
diff --git a/aio/content/guide/attribute-directives.md b/aio/content/guide/attribute-directives.md index 57fc788f14..b353d05d0a 100644 --- a/aio/content/guide/attribute-directives.md +++ b/aio/content/guide/attribute-directives.md @@ -39,7 +39,7 @@ Two examples are [NgFor](guide/template-syntax#ngFor) and [NgIf](guide/template- Learn about them in the [Structural Directives](guide/structural-directives) guide. *Attribute directives* are used as attributes of elements. -The built-in [NgStyle](guide/template-syntax#ngStyle) directive in the +The built-in [NgStyle](guide/template-syntax#ngStyle) directive in the [Template Syntax](guide/template-syntax) guide, for example, can change several element styles at the same time. @@ -108,7 +108,7 @@ they don't conflict with standard HTML attributes. This also reduces the risk of colliding with third-party directive names. Make sure you do **not** prefix the `highlight` directive name with **`ng`** because -that prefix is reserved for Angular and using it could cause bugs that are difficult to diagnose. +that prefix is reserved for Angular and using it could cause bugs that are difficult to diagnose. For a simple demo, the short prefix, `my`, helps distinguish your custom directive. @@ -116,7 +116,7 @@ For a simple demo, the short prefix, `my`, helps distinguish your custom directi -After the `@Directive` metadata comes the directive's controller class, +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. @@ -168,7 +168,7 @@ Now when the app runs, the `myHighlight` directive highlights the paragraph text
- First Highlight + First Highlight
@@ -179,7 +179,7 @@ Now when the app runs, the `myHighlight` directive highlights the paragraph text ### Your directive isn't working? -Did you remember to add the directive to the `declarations` attribute of `@NgModule`? +Did you remember to add the directive to the `declarations` attribute of `@NgModule`? It is easy to forget! Open the console in the browser tools and look for an error like this: @@ -236,7 +236,7 @@ each adorned by the `HostListener` decorator. -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. @@ -280,7 +280,7 @@ the mouse hovers over the `p` and disappears as it moves out.

- Second Highlight + Second Highlight
@@ -438,7 +438,7 @@ Here are the harness and directive in action.
- Highlight v.2 + Highlight v.2
@@ -491,7 +491,7 @@ Here's how the harness should work when you're done coding.
- Final Highlight + Final Highlight
@@ -607,4 +607,4 @@ Now apply that reasoning to the following example: * 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. \ No newline at end of file + Therefore, the directive property must carry the `@Input` decorator. diff --git a/aio/content/guide/cli-quickstart.md b/aio/content/guide/cli-quickstart.md index f593e34892..fe1581581b 100644 --- a/aio/content/guide/cli-quickstart.md +++ b/aio/content/guide/cli-quickstart.md @@ -123,7 +123,7 @@ Your app greets you with a message:
- The app works! + The app works!
@@ -161,7 +161,7 @@ Open `src/app/app.component.css` and give the component some style.
- Output of QuickStart app + Output of QuickStart app
diff --git a/aio/content/guide/component-communication.md b/aio/content/guide/component-communication.md index 68a6d70847..2cee231bc3 100644 --- a/aio/content/guide/component-communication.md +++ b/aio/content/guide/component-communication.md @@ -54,7 +54,7 @@ The running application displays three heroes:
- Parent-to-child + Parent-to-child
@@ -98,7 +98,7 @@ Here's the `NameParentComponent` demonstrating name variations including a name
- Parent-to-child-setter + Parent-to-child-setter
@@ -156,7 +156,7 @@ Here's the output of a button-pushing sequence:
- Parent-to-child-onchanges + Parent-to-child-onchanges
@@ -210,7 +210,7 @@ and the method processes it:
- Child-to-parent + Child-to-parent
@@ -272,7 +272,7 @@ Here we see the parent and child working together.
- countdown timer + countdown timer
@@ -309,7 +309,7 @@ must read or write child component values or must call child component methods. When the parent component *class* requires that kind of access, ***inject*** the child component into the parent as a *ViewChild*. -The following example illustrates this technique with the same +The following example illustrates this technique with the same [Countdown Timer](guide/component-communication#countdown-timer-example) example. Neither its appearance nor its behavior will change. The child [CountdownTimerComponent](guide/component-communication#countdown-timer-example) is the same as well. @@ -424,7 +424,7 @@ facilitated by the service:
- bidirectional-service + bidirectional-service
@@ -441,4 +441,4 @@ and verify that the history meets expectations: -[Back to top](guide/component-communication#top) \ No newline at end of file +[Back to top](guide/component-communication#top) diff --git a/aio/content/guide/dependency-injection-in-action.md b/aio/content/guide/dependency-injection-in-action.md index f5c3608390..5768883ae2 100644 --- a/aio/content/guide/dependency-injection-in-action.md +++ b/aio/content/guide/dependency-injection-in-action.md @@ -171,7 +171,7 @@ Once all the dependencies are in place, the `AppComponent` displays the user inf
- Logged In User + Logged In User
@@ -337,7 +337,7 @@ Find this example in live co and confirm that the three `HeroBioComponent` instances have their own cached hero data.
- Bios + Bios
@@ -403,7 +403,7 @@ placing it in the `` slot of the `HeroBioComponent` template: It looks like this, with the hero's telephone number from `HeroContactComponent` projected above the hero description:
- bio and contact + bio and contact
@@ -440,7 +440,7 @@ Thanks to `@Optional()`, Angular sets the `loggerService` to null and the rest o Here's the `HeroBiosAndContactsComponent` in action.
- Bios with contact into + Bios with contact into
@@ -450,7 +450,7 @@ until it finds the logger at the `AppComponent` level. The logger logic kicks in with the gratuitous "!!!", indicating that the logger was found.
- Without @Host + Without @Host
@@ -495,7 +495,7 @@ first without a value (yielding the default color) and then with an assigned col The following image shows the effect of mousing over the `` tag.
- Highlighted bios + Highlighted bios
{@a providers} @@ -570,10 +570,10 @@ But not every dependency can be satisfied by creating a new instance of a class. You need other ways to deliver dependency values and that means you need other ways to specify a provider. The `HeroOfTheMonthComponent` example demonstrates many of the alternatives and why you need them. -It's visually simple: a few properties and the logs produced by a logger. +It's visually simple: a few properties and the logs produced by a logger.
- Hero of the month + Hero of the month
@@ -595,7 +595,7 @@ The code behind it gives you plenty to think about. The `provide` object literal takes a *token* and a *definition object*. The *token* is usually a class but [it doesn't have to be](guide/dependency-injection-in-action#tokens). -The *definition* object has a required property that specifies how to create the singleton instance of the service. In this case, the property. +The *definition* object has a required property that specifies how to create the singleton instance of the service. In this case, the property. @@ -728,7 +728,7 @@ Now put it to use in a simplified version of the `HeroOfTheMonthComponent`. The `HeroOfTheMonthComponent` constructor's `logger` parameter is typed as `MinimalLogger` so only the `logs` and `logInfo` members are visible in a TypeScript-aware editor:
- MinimalLogger restricted API + MinimalLogger restricted API
@@ -743,7 +743,7 @@ Behind the scenes, Angular actually sets the `logger` parameter to the full serv The following image, which displays the logging date, confirms the point:
- DateLoggerService entry + DateLoggerService entry
@@ -849,7 +849,7 @@ But *no class* in this application inherits from `MinimalLogger`. The `LoggerService` and the `DateLoggerService` _could_ have inherited from `MinimalLogger`. They could have _implemented_ it instead in the manner of an interface. -But they did neither. +But they did neither. The `MinimalLogger` is used exclusively as a dependency injection token. When you use a class this way, it's called a ***class-interface***. @@ -941,7 +941,7 @@ to display a *sorted* list of heroes.
- Sorted Heroes + Sorted Heroes
@@ -1003,8 +1003,8 @@ These complications argue for *avoiding component inheritance*. ## Find a parent component by injection Application components often need to share information. -More loosely coupled techniques such as data binding and service sharing -are preferable. But sometimes it makes sense for one component +More loosely coupled techniques such as data binding and service sharing +are preferable. But sometimes it makes sense for one component to have a direct reference to another component perhaps to access values or call methods on that component. @@ -1013,7 +1013,7 @@ Although an Angular application is a tree of components, there is no public API for inspecting and traversing that tree. There is an API for acquiring a child reference. -Check out `Query`, `QueryList`, `ViewChildren`, and `ContentChildren` +Check out `Query`, `QueryList`, `ViewChildren`, and `ContentChildren` in the [API Reference](api/). There is no public API for acquiring a parent reference. @@ -1050,7 +1050,7 @@ after injecting an `AlexComponent` into her constructor: -Notice that even though the [@Optional](guide/dependency-injection-in-action#optional) qualifier +Notice that even though the [@Optional](guide/dependency-injection-in-action#optional) qualifier is there for safety, the confirms that the `alex` parameter is set. @@ -1078,8 +1078,8 @@ whose API your `NewsComponent` understands. Looking for components that implement an interface would be better. -That's not possible because TypeScript interfaces disappear -from the transpiled JavaScript, which doesn't support interfaces. +That's not possible because TypeScript interfaces disappear +from the transpiled JavaScript, which doesn't support interfaces. There's no artifact to look for. @@ -1087,7 +1087,7 @@ There's no artifact to look for. This isn't necessarily good design. -This example is examining *whether a component can +This example is examining *whether a component can inject its parent via the parent's base class*. The sample's `CraigComponent` explores this question. [Looking back](guide/dependency-injection-in-action#alex), @@ -1126,7 +1126,7 @@ The parent must cooperate by providing an *alias* to itself in the name of a *cl Recall that Angular always adds a component instance to its own injector; that's why you could inject *Alex* into *Cathy* [earlier](guide/dependency-injection-in-action#known-parent). -Write an [*alias provider*](guide/dependency-injection-in-action#useexisting)—a `provide` object literal with a `useExisting` +Write an [*alias provider*](guide/dependency-injection-in-action#useexisting)—a `provide` object literal with a `useExisting` definition—that creates an *alternative* way to inject the same component instance and add that provider to the `providers` array of the `@Component` metadata for the `AlexComponent`: @@ -1142,7 +1142,7 @@ and add that provider to the `providers` array of the `@Component` metadata for [Parent](guide/dependency-injection-in-action#parent-token) is the provider's *class-interface* token. The [*forwardRef*](guide/dependency-injection-in-action#forwardref) breaks the circular reference you just created by having the `AlexComponent` refer to itself. -*Carol*, the third of *Alex*'s child components, injects the parent into its `parent` parameter, +*Carol*, the third of *Alex*'s child components, injects the parent into its `parent` parameter, the same way you've done it before: @@ -1154,7 +1154,7 @@ the same way you've done it before: Here's *Alex* and family in action:
- Alex in action + Alex in action
@@ -1215,7 +1215,7 @@ Here's *Alice*, *Barry* and family in action:
- Alice in action + Alice in action
diff --git a/aio/content/guide/displaying-data.md b/aio/content/guide/displaying-data.md index 2f48103595..d28bcdce89 100644 --- a/aio/content/guide/displaying-data.md +++ b/aio/content/guide/displaying-data.md @@ -18,7 +18,7 @@ The final UI looks like this:
- Final UI + Final UI
@@ -126,7 +126,7 @@ inside the `` tag. Now run the app. It should display the title and hero name:
- Title and Hero + Title and Hero
@@ -233,7 +233,7 @@ Now the heroes appear in an unordered list.
- After ngfor + After ngfor
diff --git a/aio/content/guide/dynamic-component-loader.md b/aio/content/guide/dynamic-component-loader.md index d150eba494..ff7c34cb5b 100644 --- a/aio/content/guide/dynamic-component-loader.md +++ b/aio/content/guide/dynamic-component-loader.md @@ -102,8 +102,8 @@ because it doesn't render any additional output. Take a closer look at the methods in `ad-banner.component.ts`. `AdBannerComponent` takes an array of `AdItem` objects as input, -which ultimately comes from `AdService`. `AdItem` objects specify -the type of component to load and any data to bind to the +which ultimately comes from `AdService`. `AdItem` objects specify +the type of component to load and any data to bind to the component.`AdService` returns the actual ads making up the ad campaign. Passing an array of components to `AdBannerComponent` allows for a @@ -141,17 +141,17 @@ value to select an `adItem` from the array. -After `loadComponent()` selects an ad, it uses `ComponentFactoryResolver` -to resolve a `ComponentFactory` for each specific component. +After `loadComponent()` selects an ad, it uses `ComponentFactoryResolver` +to resolve a `ComponentFactory` for each specific component. The `ComponentFactory` then creates an instance of each component. -Next, you're targeting the `viewContainerRef` that -exists on this specific instance of the component. How do you know it's -this specific instance? Because it's referring to `adHost` and `adHost` is the +Next, you're targeting the `viewContainerRef` that +exists on this specific instance of the component. How do you know it's +this specific instance? Because it's referring to `adHost` and `adHost` is the directive you set up earlier to tell Angular where to insert dynamic components. -As you may recall, `AdDirective` injects `ViewContainerRef` into its constructor. -This is how the directive accesses the element that you want to use to host the dynamic component. +As you may recall, `AdDirective` injects `ViewContainerRef` into its constructor. +This is how the directive accesses the element that you want to use to host the dynamic component. To add the component to the template, you call `createComponent()` on `ViewContainerRef`. @@ -214,9 +214,9 @@ Here are two sample components and the `AdComponent` interface for reference: The final ad banner looks like this:
- Ads + Ads
-See the . \ No newline at end of file +See the . diff --git a/aio/content/guide/dynamic-form.md b/aio/content/guide/dynamic-form.md index 39208799f5..ef446e6e92 100644 --- a/aio/content/guide/dynamic-form.md +++ b/aio/content/guide/dynamic-form.md @@ -7,20 +7,20 @@ Render dynamic forms with FormGroup. @description -Building handcrafted forms can be costly and time-consuming, +Building handcrafted forms can be costly and time-consuming, especially if you need a great number of them, they're similar to each other, and they change frequently to meet rapidly changing business and regulatory requirements. -It may be more economical to create the forms dynamically, based on +It may be more economical to create the forms dynamically, based on metadata that describes the business object model. -This cookbook shows you how to use `formGroup` to dynamically +This cookbook shows you how to use `formGroup` to dynamically render a simple form with different control types and validation. It's a primitive start. It might evolve to support a much richer variety of questions, more graceful rendering, and superior user experience. All such greatness has humble beginnings. -The example in this cookbook is a dynamic form to build an +The example in this cookbook is a dynamic form to build an online application experience for heroes seeking employment. The agency is constantly tinkering with the application process. You can create the forms on the fly *without changing the application code*. @@ -44,8 +44,8 @@ Start by creating an `NgModule` called `AppModule`. This cookbook uses [reactive forms](guide/reactive-forms). -Reactive forms belongs to a different `NgModule` called `ReactiveFormsModule`, -so in order to access any reactive forms directives, you have to import +Reactive forms belongs to a different `NgModule` called `ReactiveFormsModule`, +so in order to access any reactive forms directives, you have to import `ReactiveFormsModule` from the `@angular/forms` library. Bootstrap the `AppModule` in `main.ts`. @@ -81,12 +81,12 @@ The following `QuestionBase` is a fundamental question class. -From this base you can derive two new classes in `TextboxQuestion` and `DropdownQuestion` +From this base you can derive two new classes in `TextboxQuestion` and `DropdownQuestion` that represent textbox and dropdown questions. -The idea is that the form will be bound to specific question types and render the +The idea is that the form will be bound to specific question types and render the appropriate controls dynamically. -`TextboxQuestion` supports multiple HTML5 types such as text, email, and url +`TextboxQuestion` supports multiple HTML5 types such as text, email, and url via the `type` property. @@ -106,7 +106,7 @@ via the `type` property. Next is `QuestionControlService`, a simple service for transforming the questions to a `FormGroup`. -In a nutshell, the form group consumes the metadata from the question model and +In a nutshell, the form group consumes the metadata from the question model and allows you to specify default values and validation rules. @@ -117,7 +117,7 @@ allows you to specify default values and validation rules. {@a form-component} ## Question form components -Now that you have defined the complete model you are ready +Now that you have defined the complete model you are ready to create components to represent the dynamic form. @@ -139,7 +139,7 @@ to create components to represent the dynamic form. It presents a list of questions, each bound to a `` component element. The `` tag matches the `DynamicFormQuestionComponent`, -the component responsible for rendering the details of each _individual_ +the component responsible for rendering the details of each _individual_ question based on values in the data-bound question object. @@ -164,8 +164,8 @@ The `ngSwitch` determines which type of question to display. In both components you're relying on Angular's **formGroup** to connect the template HTML to the underlying control objects, populated from the question model with display and validation rules. -`formControlName` and `formGroup` are directives defined in -`ReactiveFormsModule`. The templates can access these directives +`formControlName` and `formGroup` are directives defined in +`ReactiveFormsModule`. The templates can access these directives directly since you imported `ReactiveFormsModule` from `AppModule`. {@a questionnaire-data} @@ -176,9 +176,9 @@ directly since you imported `ReactiveFormsModule` from `AppModule`. The set of questions you've defined for the job application is returned from the `QuestionService`. In a real app you'd retrieve these questions from storage. - The key point is that you control the hero job application questions + The key point is that you control the hero job application questions entirely through the objects returned from `QuestionService`. - Questionnaire maintenance is a simple matter of adding, updating, + Questionnaire maintenance is a simple matter of adding, updating, and removing objects from the `questions` array. @@ -198,7 +198,7 @@ Finally, display an instance of the form in the `AppComponent` shell. {@a dynamic-template} ## Dynamic Template -Although in this example you're modelling a job application for heroes, there are +Although in this example you're modelling a job application for heroes, there are no references to any specific hero question outside the objects returned by `QuestionService`. @@ -217,9 +217,9 @@ Saving and retrieving the data is an exercise for another time. The final form looks like this:
- Dynamic-Form + Dynamic-Form
-[Back to top](guide/dynamic-form#top) \ No newline at end of file +[Back to top](guide/dynamic-form#top) diff --git a/aio/content/guide/forms.md b/aio/content/guide/forms.md index cacde156a3..fd8889451a 100644 --- a/aio/content/guide/forms.md +++ b/aio/content/guide/forms.md @@ -41,7 +41,7 @@ the form-specific directives and techniques described in this page. -You can also use a reactive (or model-driven) approach to build forms. +You can also use a reactive (or model-driven) approach to build forms. However, this page focuses on template-driven forms. @@ -60,7 +60,7 @@ You'll learn to build a template-driven form that looks like this:
- Clean Form + Clean Form
@@ -74,7 +74,7 @@ If you delete the hero name, the form displays a validation error in an attentio
- Invalid, Name Required + Invalid, Name Required
@@ -148,7 +148,7 @@ You can create a new hero like this: ## Create a form component -An Angular form has two parts: an HTML-based _template_ and a component _class_ +An Angular form has two parts: an HTML-based _template_ and a component _class_ to handle data and user interactions programmatically. Begin with the class because it states, in brief, what the hero editor can do. @@ -301,7 +301,7 @@ You added a *Submit* button at the bottom with some classes on it for styling. -In template driven forms, if you've imported `FormsModule`, you don't have to do anything +In template driven forms, if you've imported `FormsModule`, you don't have to do anything to the `
` tag in order to make use of `FormsModule`. Continue on to see how this works. @@ -372,7 +372,7 @@ Running the app right now would be disappointing.
- Early form with no binding + Early form with no binding
@@ -413,8 +413,8 @@ You left yourself a note to throw it away when you're done. Focus on the binding syntax: `[(ngModel)]="..."`. -You need one more addition to display the data. Declare -a template variable for the form. Update the `` tag with +You need one more addition to display the data. Declare +a template variable for the form. Update the `` tag with `#heroForm="ngForm"` as follows: @@ -456,7 +456,7 @@ At some point it might look like this:
- ngModel in action + ngModel in action
@@ -529,7 +529,7 @@ If you run the app now and change every hero model property, the form might disp
- ngModel in action + ngModel in action
@@ -642,7 +642,7 @@ The actions and effects are as follows:
- Control State Transition + Control State Transition
@@ -651,7 +651,7 @@ You should see the following transitions and class names:
- Control state transitions + Control state transitions
@@ -671,7 +671,7 @@ on the left of the input box:
- Invalid Form + Invalid Form
@@ -705,7 +705,7 @@ When the user deletes the name, the form should look like this:
- Name required + Name required
@@ -833,8 +833,8 @@ to the hero form component's `onSubmit()` method: -You'd already defined a template reference variable, -`#heroForm`, and initialized it with the value "ngForm". +You'd already defined a template reference variable, +`#heroForm`, and initialized it with the value "ngForm". Now, use that variable to access the form with the Submit button. @@ -849,7 +849,7 @@ using an event binding. Here's the code: -If you run the application now, you find that the button is enabled—although +If you run the application now, you find that the button is enabled—although it doesn't do anything useful yet. Now if you delete the Name, you violate the "required" rule, which diff --git a/aio/content/guide/hierarchical-dependency-injection.md b/aio/content/guide/hierarchical-dependency-injection.md index 5bb1ee8998..cbfabfb0ec 100644 --- a/aio/content/guide/hierarchical-dependency-injection.md +++ b/aio/content/guide/hierarchical-dependency-injection.md @@ -55,7 +55,7 @@ open simultaneously.
- injector tree + injector tree
@@ -149,7 +149,7 @@ Each tax return component has the following characteristics:
- Heroes in action + Heroes in action
@@ -234,7 +234,7 @@ Component (B) is the parent of another component (C) that defines its own, even
- car components + car components
@@ -247,7 +247,7 @@ its injector produces an instance of `Car` resolved by injector (C) with an `Eng
- car injector tree + car injector tree
diff --git a/aio/content/guide/http.md b/aio/content/guide/http.md index c9751b1e6f..5721b459aa 100644 --- a/aio/content/guide/http.md +++ b/aio/content/guide/http.md @@ -178,7 +178,7 @@ The app uses the Angular Http client to communicate via **XMLHttpRe It works like this:
- ToH mini app + ToH mini app
@@ -333,13 +333,13 @@ and `map()` is one of the RxJS *operators*. ## RxJS library RxJS -is a third party library, endorsed by Angular, that implements the +is a third party library, endorsed by Angular, that implements the asynchronous Observable pattern. All of the Developer Guide samples have installed the RxJS npm package because Observables are used widely in Angular applications. _This_ app needs it when working with the HTTP client. -But you must take a critical extra step to make RxJS Observables usable: +But you must take a critical extra step to make RxJS Observables usable: _you must import the RxJS operators individually_. ### Enable RxJS operators @@ -646,8 +646,8 @@ highlighting just the parts that are different. You can follow the Promise `then(this.extractData).catch(this.handleError)` pattern as in this example. -Alternatively, you can call `toPromise(success, fail)`. The Observable's `map` callback moves to the -first *success* parameter and its `catch` callback to the second *fail* parameter +Alternatively, you can call `toPromise(success, fail)`. The Observable's `map` callback moves to the +first *success* parameter and its `catch` callback to the second *fail* parameter in this pattern: `.toPromise(this.extractData, this.handleError)`. The `errorHandler` forwards an error message as a failed `Promise` instead of a failed `Observable`. @@ -680,15 +680,15 @@ Both methods take the same functional arguments. The less obvious but critical difference is that these two methods return very different results. -The Promise-based `then()` returns another Promise. You can keep chaining +The Promise-based `then()` returns another Promise. You can keep chaining more `then()` and `catch()` calls, getting a new promise each time. The `subscribe()` method returns a `Subscription`. A `Subscription` is not another `Observable`. It's the end of the line for Observables. You can't call `map()` on it or call `subscribe()` again. The `Subscription` object has a different purpose, signified by its primary method, `unsubscribe`. -To understand the implications and consequences of subscriptions, -watch [Ben Lesh's talk on Observables](https://www.youtube.com/watch?v=3LKMwkuK0ZE) +To understand the implications and consequences of subscriptions, +watch [Ben Lesh's talk on Observables](https://www.youtube.com/watch?v=3LKMwkuK0ZE) or his video course on [egghead.io](https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises). @@ -746,7 +746,7 @@ types in a text box:
- Wikipedia search app (v.1) + Wikipedia search app (v.1)
@@ -831,7 +831,7 @@ turn your attention to the component (template and class) that takes user input The template presents an `` element *search box* to gather search terms from the user, and calls a `search(term)` method after each `keyup` event. -The component's `search(term)` method delegates to the `WikipediaService`, which returns an +The component's `search(term)` method delegates to the `WikipediaService`, which returns an Observable array of string results (`Observable`). Instead of subscribing to the Observable inside the component, as in the `HeroListComponent`, the app forwards the Observable result to the template (via `items`) where the `async` pipe @@ -865,7 +865,7 @@ It should only make requests when the user *stops typing*. Here's how it will work after refactoring:
- Wikipedia search app (v.2) + Wikipedia search app (v.2)
diff --git a/aio/content/guide/lifecycle-hooks.md b/aio/content/guide/lifecycle-hooks.md index 5f02382852..d0bffab4a9 100644 --- a/aio/content/guide/lifecycle-hooks.md +++ b/aio/content/guide/lifecycle-hooks.md @@ -9,7 +9,7 @@ Angular calls lifecycle hook methods on directives and components as it creates,
- Us + Us
@@ -262,7 +262,7 @@ calls the lifecycle hook methods in the following sequence at specific moments: {@a interface-optional} - + ## Interfaces are optional (technically) @@ -465,7 +465,7 @@ The peek-a-boo exists to show how Angular calls the hooks in the expected order. This snapshot reflects the state of the log after the user clicked the *Create...* button and then the *Destroy...* button.
- Peek-a-boo + Peek-a-boo
@@ -549,7 +549,7 @@ with an entry in the *Hook Log* as seen here:
- Spy Directive + Spy Directive
@@ -672,7 +672,7 @@ Here's the sample in action as the user makes changes.
- OnChanges + OnChanges
@@ -718,7 +718,7 @@ so you can see how often `DoCheck` is called. The results are illuminating:
- DoCheck + DoCheck
@@ -788,14 +788,14 @@ Angular's unidirectional data flow rule forbids updates to the view *after* it h 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!). -The `LoggerService.tick_then()` postpones the log update +The `LoggerService.tick_then()` postpones the log update for one turn of the browser's JavaScript cycle and that's just long enough. Here's *AfterView* in action:
- AfterView + AfterView
@@ -859,7 +859,7 @@ It tells Angular where to insert that content. In this case, the projected content is the `` from the parent.
- Projected Content + Projected Content
@@ -915,4 +915,4 @@ There's no [need to wait](guide/lifecycle-hooks#wait-a-tick). Recall that Angular calls both *AfterContent* hooks before calling either of the *AfterView* hooks. Angular completes composition of the projected content *before* finishing the composition of this component's view. -There is a small window between the `AfterContent...` and `AfterView...` hooks to modify the host view. \ No newline at end of file +There is a small window between the `AfterContent...` and `AfterView...` hooks to modify the host view. diff --git a/aio/content/guide/pipes.md b/aio/content/guide/pipes.md index a8b85fe0f8..aabfc86ae6 100644 --- a/aio/content/guide/pipes.md +++ b/aio/content/guide/pipes.md @@ -145,7 +145,7 @@ As you click the button, the displayed date alternates between
- Date Format Toggle + Date Format Toggle
@@ -237,7 +237,7 @@ Now you need a component to demonstrate the pipe.
- Power Booster + Power Booster
@@ -285,7 +285,7 @@ your pipe and two-way data binding with `ngModel`.
- Power Boost Calculator + Power Boost Calculator
@@ -372,7 +372,7 @@ code with checkbox switches and additional displays to help you experience these
- Flying Heroes + Flying Heroes
@@ -559,7 +559,7 @@ The component renders as the following:
- Hero List + Hero List
@@ -674,4 +674,4 @@ Any capabilities that you would have put in a pipe and shared across the app can written in a filtering/sorting service and injected into the component. If these performance and minification considerations don't apply to you, you can always create your own such pipes -(similar to the [FlyingHeroesPipe](guide/pipes#impure-flying-heroes)) or find them in the community. \ No newline at end of file +(similar to the [FlyingHeroesPipe](guide/pipes#impure-flying-heroes)) or find them in the community. diff --git a/aio/content/guide/reactive-forms.md b/aio/content/guide/reactive-forms.md index f9d6eec5a4..711c8cf863 100644 --- a/aio/content/guide/reactive-forms.md +++ b/aio/content/guide/reactive-forms.md @@ -53,57 +53,57 @@ But they diverge markedly in philosophy, programming style, and technique. They even have their own modules: the `ReactiveFormsModule` and the `FormsModule`. ### _Reactive_ forms -Angular _reactive_ forms facilitate a _reactive style_ of programming +Angular _reactive_ forms facilitate a _reactive style_ of programming that favors explicit management of the data flowing between -a non-UI _data model_ (typically retrieved from a server) and a -UI-oriented _form model_ that retains the states -and values of the HTML controls on screen. Reactive forms offer the ease +a non-UI _data model_ (typically retrieved from a server) and a +UI-oriented _form model_ that retains the states +and values of the HTML controls on screen. Reactive forms offer the ease of using reactive patterns, testing, and validation. With _reactive_ forms, you create a tree of Angular form control objects -in the component class and bind them to native form control elements in the -component template, using techniques described in this guide. +in the component class and bind them to native form control elements in the +component template, using techniques described in this guide. -You create and manipulate form control objects directly in the -component class. As the component class has immediate access to both the data -model and the form control structure, you can push data model values into -the form controls and pull user-changed values back out. The component can +You create and manipulate form control objects directly in the +component class. As the component class has immediate access to both the data +model and the form control structure, you can push data model values into +the form controls and pull user-changed values back out. The component can observe changes in form control state and react to those changes. -One advantage of working with form control objects directly is that value and validity updates -are [always synchronous and under your control](guide/reactive-forms#async-vs-sync "Async vs sync"). +One advantage of working with form control objects directly is that value and validity updates +are [always synchronous and under your control](guide/reactive-forms#async-vs-sync "Async vs sync"). You won't encounter the timing issues that sometimes plague a template-driven form and reactive forms can be easier to unit test. -In keeping with the reactive paradigm, the component +In keeping with the reactive paradigm, the component preserves the immutability of the _data model_, treating it as a pure source of original values. -Rather than update the data model directly, -the component extracts user changes and forwards them to an external component or service, -which does something with them (such as saving them) -and returns a new _data model_ to the component that reflects the updated model state. - -Using reactive form directives does not require you to follow all reactive priniciples, +Rather than update the data model directly, +the component extracts user changes and forwards them to an external component or service, +which does something with them (such as saving them) +and returns a new _data model_ to the component that reflects the updated model state. + +Using reactive form directives does not require you to follow all reactive priniciples, but it does facilitate the reactive programming approach should you choose to use it. ### _Template-driven_ forms _Template-driven_ forms, introduced in the [Template guide](guide/forms), take a completely different approach. -You place HTML form controls (such as `` and `` and ``. +To let Angular know that this is the input that you want to +associate to the `name` `FormControl` in the class, +you need `[formControl]="name"` in the template on the ``. @@ -265,7 +265,7 @@ you need `[formControl]="name"` in the template on the ``. -Disregard the `form-control` _CSS_ class. It belongs to the +Disregard the `form-control` _CSS_ class. It belongs to the Bootstrap CSS library, not Angular. It _styles_ the form but in no way impacts the logic of the form. @@ -280,13 +280,13 @@ It _styles_ the form but in no way impacts the logic of the form. ## Import the _ReactiveFormsModule_ -The HeroDetailComponent template uses `formControlName` +The HeroDetailComponent template uses `formControlName` directive from the `ReactiveFormsModule`. In this sample, you declare the `HeroDetailComponent` in the `AppModule`. Therefore, do the following three things in `app.module.ts`: -1. Use a JavaScript `import` statement to access +1. Use a JavaScript `import` statement to access the `ReactiveFormsModule` and the `HeroDetailComponent`. 1. Add `ReactiveFormsModule` to the `AppModule`'s `imports` list. 1. Add `HeroDetailComponent` to the declarations array. @@ -318,11 +318,11 @@ Revise the `AppComponent` template so it displays the `HeroDetailComponent`. It may be helpful to read a brief description of the core form classes. * [_AbstractControl_](api/forms/index/AbstractControl-class "API Reference: AbstractControl") -is the abstract base class for the three concrete form control classes: +is the abstract base class for the three concrete form control classes: `FormControl`, `FormGroup`, and `FormArray`. It provides their common behaviors and properties, some of which are _observable_. -* [_FormControl_](api/forms/index/FormControl-class "API Reference: FormControl") +* [_FormControl_](api/forms/index/FormControl-class "API Reference: FormControl") tracks the value and validity status of an _individual_ form control. It corresponds to an HTML form control such as an input box or selector. @@ -349,11 +349,11 @@ Add the `bootstrap` _CSS stylesheet_ to the head of `index.html`: -Now that everything is wired up, the browser should display something like this: +Now that everything is wired up, the browser should display something like this:
- Single FormControl + Single FormControl
@@ -362,9 +362,9 @@ Now that everything is wired up, the browser should display something like this: ## Add a FormGroup -Usually, if you have multiple *FormControls*, you'll want to register +Usually, if you have multiple *FormControls*, you'll want to register them within a parent `FormGroup`. -This is simple to do. To add a `FormGroup`, add it to the imports section +This is simple to do. To add a `FormGroup`, add it to the imports section of `hero-detail.component.ts`: @@ -383,7 +383,7 @@ In the class, wrap the `FormControl` in a `FormGroup` called `heroForm` as follo -Now that you've made changes in the class, they need to be reflected in the +Now that you've made changes in the class, they need to be reflected in the template. Update `hero-detail.component.html` by replacing it with the following. @@ -393,26 +393,26 @@ template. Update `hero-detail.component.html` by replacing it with the following -Notice that now the single input is in a `form` element. The `novalidate` -attribute in the `` element prevents the browser -from attempting native HTML validations. +Notice that now the single input is in a `form` element. The `novalidate` +attribute in the `` element prevents the browser +from attempting native HTML validations. -`formGroup` is a reactive form directive that takes an existing -`FormGroup` instance and associates it with an HTML element. -In this case, it associates the `FormGroup` you saved as +`formGroup` is a reactive form directive that takes an existing +`FormGroup` instance and associates it with an HTML element. +In this case, it associates the `FormGroup` you saved as `heroForm` with the form element. -Because the class now has a `FormGroup`, you must update the template -syntax for associating the input with the corresponding -`FormControl` in the component class. -Without a parent `FormGroup`, -`[formControl]="name"` worked earlier because that directive -can stand alone, that is, it works without being in a `FormGroup`. -With a parent `FormGroup`, the `name` input needs the syntax -`formControlName=name` in order to be associated -with the correct `FormControl` -in the class. This syntax tells Angular to look for the parent -`FormGroup`, in this case `heroForm`, and then _inside_ that group +Because the class now has a `FormGroup`, you must update the template +syntax for associating the input with the corresponding +`FormControl` in the component class. +Without a parent `FormGroup`, +`[formControl]="name"` worked earlier because that directive +can stand alone, that is, it works without being in a `FormGroup`. +With a parent `FormGroup`, the `name` input needs the syntax +`formControlName=name` in order to be associated +with the correct `FormControl` +in the class. This syntax tells Angular to look for the parent +`FormGroup`, in this case `heroForm`, and then _inside_ that group to look for a `FormControl` called `name`. @@ -420,10 +420,10 @@ to look for a `FormControl` called `name`. -Disregard the `form-group` _CSS_ class. It belongs to the +Disregard the `form-group` _CSS_ class. It belongs to the Bootstrap CSS library, not Angular. -Like the `form-control` class, it _styles_ the form +Like the `form-control` class, it _styles_ the form but in no way impacts its logic. @@ -432,8 +432,8 @@ but in no way impacts its logic. -The form looks great. But does it work? -When the user enters a name, where does the value go? +The form looks great. But does it work? +When the user enters a name, where does the value go? {@a json} @@ -442,7 +442,7 @@ When the user enters a name, where does the value go? ## Taking a look at the form model The value goes into the **_form model_** that backs the group's `FormControls`. -To see the form model, add the following line after the +To see the form model, add the following line after the closing `form` tag in the `hero-detail.component.html`: @@ -457,20 +457,20 @@ Piping it through the `JsonPipe` renders the model as JSON in the browser:
- JSON output + JSON output
-The initial `name` property value is the empty string. +The initial `name` property value is the empty string. Type into the _name_ input box and watch the keystokes appear in the JSON. -Great! You have the basics of a form. +Great! You have the basics of a form. -In real life apps, forms get big fast. +In real life apps, forms get big fast. `FormBuilder` makes form development and maintenance easier. @@ -481,8 +481,8 @@ In real life apps, forms get big fast. ## Introduction to _FormBuilder_ -The `FormBuilder` class helps reduce repetition and -clutter by handling details of control creation for you. +The `FormBuilder` class helps reduce repetition and +clutter by handling details of control creation for you. To use `FormBuilder`, you need to import it into `hero-detail.component.ts`: @@ -509,7 +509,7 @@ The revised `HeroDetailComponent` looks like this: `FormBuilder.group` is a factory method that creates a `FormGroup`.   -`FormBuilder.group` takes an object whose keys and values are `FormControl` names and their definitions. +`FormBuilder.group` takes an object whose keys and values are `FormControl` names and their definitions. In this example, the `name` control is defined by its initial data value, an empty string. Defining a group of controls in a single object makes for a compact, readable style. @@ -520,8 +520,8 @@ It beats writing an equivalent series of `new FormControl(...)` statements. ### Validators.required -Though this guide doesn't go deeply into validations, here is one example that -demonstrates the simplicity of using `Validators.required` in reactive forms. +Though this guide doesn't go deeply into validations, here is one example that +demonstrates the simplicity of using `Validators.required` in reactive forms. First, import the `Validators` symbol. @@ -531,8 +531,8 @@ First, import the `Validators` symbol. -To make the `name` `FormControl` required, replace the `name` -property in the `FormGroup` with an array. +To make the `name` `FormControl` required, replace the `name` +property in the `FormGroup` with an array. The first item is the initial value for `name`; the second is the required validator, `Validators.required`. @@ -548,7 +548,7 @@ the second is the required validator, `Validators.required`. Reactive validators are simple, composable functions. -Configuring validation is harder in template-driven forms where you must wrap validators in a directive. +Configuring validation is harder in template-driven forms where you must wrap validators in a directive. @@ -567,29 +567,29 @@ The browser displays the following:
- Single FormControl + Single FormControl
`Validators.required` is working. The status is `INVALID` because the input box has no value. -Type into the input box to see the status change from `INVALID` to `VALID`. +Type into the input box to see the status change from `INVALID` to `VALID`. In a real app, you'd replace the diagnosic message with a user-friendly experience. -Using `Validators.required` is optional for the rest of the guide. +Using `Validators.required` is optional for the rest of the guide. It remains in each of the following examples with the same configuration. For more on validating Angular forms, see the -[Form Validation](cookbook/form-validation) guide. +[Form Validation](cookbook/form-validation) guide. ### More FormControls -A hero has more than a name. -A hero has an address, a super power and sometimes a sidekick too. +A hero has more than a name. +A hero has an address, a super power and sometimes a sidekick too. -The address has a state property. The user will select a state with a `` box and you'll populate the `