docs(forms): add link to Dart sample (#2176)

Contributes to #1598.

Also:
- Trimmed trailing whitespace.
- Fixing user-input (since we don’t need the “Run the” in the link).
This commit is contained in:
Patrice Chalin 2016-08-22 15:41:13 -07:00 committed by Kathy Walrath
parent 9b3614d151
commit fcaf8fa365
4 changed files with 52 additions and 51 deletions

View File

@ -1,6 +1,5 @@
include ../_util-fns
<!-- http://plnkr.co/edit/wg154K -->
:marked
Weve 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.
@ -30,6 +29,8 @@ include ../_util-fns
- How to share information across controls with template reference variables
Run the <live-example></live-example>.
.l-main-section
:marked
## Template-driven forms

View File

@ -6,7 +6,7 @@ include ../_util-fns
In this chapter we learn to bind to those events using the Angular
event binding syntax.
<live-example>Run the live example</live-example>.
Run the <live-example></live-example>.
:marked
## Binding to user input events

View File

@ -21,15 +21,15 @@ include ../_util-fns
- two-way data bind with `[(ngModel)]` syntax for reading and writing values to input controls
- track the change state and validity of form controls using `ngModel` in combination with a form
- track the change state and validity of form controls using `ngModel` in combination with a form
- provide strong visual feedback using special CSS classes that track the state of the controls
- display validation errors to users and enable/disable form controls
- use [template reference variables](./template-syntax.html#ref-vars) for sharing information among HTML elements
<live-example>Live Example</live-example>
Run the <live-example></live-example>.
.l-main-section
:marked
@ -107,13 +107,13 @@ include ../_quickstart_repo
The TypeScript compiler generates a public field for each `public` constructor parameter and
assigns the parameters value to that field automatically when we create new heroes.
The `alterEgo` is optional and the constructor lets us omit it; note the (?) in `alterEgo?`.
We can create a new hero like this:
code-example(format="").
let myHero = new Hero(42, 'SkyDog',
'Fetch any object at any distance',
let myHero = new Hero(42, 'SkyDog',
'Fetch any object at any distance',
'Leslie Rollover');
console.log('My hero is called ' + myHero.name); // "My hero is called SkyDog"
:marked
@ -159,7 +159,7 @@ code-example(format="").
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.
We made a good choice to put the HTML template elsewhere.
We made a good choice to put the HTML template elsewhere.
We'll write that template 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 our new `HeroFormComponent`.
@ -191,7 +191,7 @@ code-example(format="").
.alert.is-important
:marked
If a component, directive, or pipe belongs to a module in the `imports` array, _DON'T_ declare it in the `declarations` array.
If a component, directive, or pipe belongs to a module in the `imports` array, _DON'T_ declare it in the `declarations` array.
If you wrote it and it should belong to this module, _DO_ declare it in the `declarations` array.
.l-main-section
@ -230,7 +230,7 @@ code-example(format="").
**We are not using Angular yet**. There are no bindings. No extra directives. Just layout.
The `container`, `form-group`, `form-control`, and `btn` classes
The `container`, `form-group`, `form-control`, and `btn` classes
come from [Twitter Bootstrap](http://getbootstrap.com/css/). Purely cosmetic.
We're using Bootstrap to gussy up our form.
Hey, what's a form without a little style!
@ -300,7 +300,7 @@ figure.image-display
We appended a diagnostic interpolation after the input tag
so we can see what we're doing.
We left ourselves a note to throw it away when we're done.
:marked
Focus on the binding syntax: `[(ngModel)]="..."`.
@ -314,13 +314,13 @@ figure.image-display
The diagnostic is evidence that we really are flowing values from the input box to the model and
back again. **That's two-way data binding!**
Notice that we also added a `name` attribute to our `<input>` tag and set it to "name"
Notice that we also added a `name` attribute to our `<input>` tag and set it to "name"
which makes sense for the hero's name. Any unique value will do, but using a descriptive name is helpful.
Defining a `name` attribute is a requirement when using `[(ngModel)]` in combination with a form.
.l-sub-section
:marked
Internally Angular creates `FormControls` and registers them with an `NgForm` directive that Angular
Internally Angular creates `FormControls` and registers them with an `NgForm` directive that Angular
attached to the `<form>` tag. Each `FormControl` is registered under the name we assigned to the `name` attribute.
We'll talk about `NgForm` [later in this chapter](#ngForm).
@ -340,7 +340,7 @@ figure.image-display
- Each input element has an `id` property that is used by the `label` element's `for` attribute
to match the label to it's input control.
- Each input element has a `name` property that is required by Angular Forms to register the control with the form.
:marked
If we ran the app right now and changed every Hero model property, the form might display like this:
figure.image-display
@ -355,7 +355,7 @@ figure.image-display
:marked
### Inside [(ngModel)]
*This section is an optional deep dive into [(ngModel)]. Not interested? Skip ahead!*
The punctuation in the binding syntax, <span style="font-family:courier"><b>[()]</b></span>, is a good clue to what's going on.
In a Property Binding, a value flows from the model to a target property on screen.
@ -405,7 +405,7 @@ figure.image-display
The *NgModel* directive doesn't just track state; it updates the control with special Angular CSS classes that reflect the state.
We can leverage those class names to change the appearance of the
control and make messages appear or disappear.
table
tr
th State
@ -491,32 +491,32 @@ figure.image-display
1. the "*is required*" message in a nearby `<div>` which we'll display only if the control is invalid.
Here's how we do it for the *name* input box:
+makeExample('forms/ts/app/hero-form.component.html',
'name-with-error-msg',
+makeExample('forms/ts/app/hero-form.component.html',
'name-with-error-msg',
'app/hero-form.component.html (excerpt)')(format=".")
:marked
We need a template reference variable to access the input box's Angular control from within the template.
Here we created a variable called `name` and gave it the value "ngModel".
.l-sub-section
:marked
Why "ngModel"?
Why "ngModel"?
A directive's [exportAs](../api/core/index/DirectiveMetadata-class.html#!#exportAs-anchor) property
tells Angular how to link the reference variable to the directive.
We set `name` to `ngModel` because the `ngModel` directive's `exportAs` property happens to be "ngModel".
Now we can control visibility of the "name" error message by binding properties of the `name` control to the message `<div>` element's `hidden` property.
+makeExample('forms/ts/app/hero-form.component.html',
'hidden-error-msg',
+makeExample('forms/ts/app/hero-form.component.html',
'hidden-error-msg',
'app/hero-form.component.html (excerpt)')
:marked
In this example, we hide the message when the control is valid or pristine;
pristine means the user hasn't changed the value since it was displayed in this form.
In this example, we hide the message when the control is valid or pristine;
pristine means the user hasn't changed the value since it was displayed in this form.
This user experience is the developer's choice. Some folks want to see the message at all times.
If we ignore the `pristine` state, we would hide the message only when the value is valid.
If we arrive in this component with a new (blank) hero or an invalid hero,
If we arrive in this component with a new (blank) hero or an invalid hero,
we'll see the error message immediately, before we've done anything.
Some folks find that behavior disconcerting. They only want to see the message when the user makes an invalid change.
Hiding the message while the control is "pristine" achieves that goal.
We'll see the significance of this choice when we [add a new hero](#new-hero) to the form.
@ -527,30 +527,30 @@ figure.image-display
We can add the same kind of error handling to the `<select>` if we want
but it's not imperative because the selection box already constrains the
power to valid value.
<a id="new-hero"></a>
<a id="reset"></a>
<a id="reset"></a>
.l-main-section
:marked
## Add a hero and reset the form
We'd like to add a new hero in this form.
We'd like to add a new hero in this form.
We place a "New Hero" button at the bottom of the form and bind its click event to a component method.
+makeExample('forms/ts/app/hero-form.component.html',
'new-hero-button',
+makeExample('forms/ts/app/hero-form.component.html',
'new-hero-button',
'app/hero-form.component.html (New Hero button)')
:marked
+makeExample('forms/ts/app/hero-form.component.ts',
'new-hero-v1',
+makeExample('forms/ts/app/hero-form.component.ts',
'new-hero-v1',
'app/hero-form.component.ts (New Hero method - v1)')(format=".")
:marked
Run the application again, click the *New Hero* button, and the form clears.
The *required* bars to the left of the input box are red, indicating invalid `name` and `power` properties.
That's understandable as these are required fields.
That's understandable as these are required fields.
The error messages are hidden because the form is pristine; we haven't changed anything yet.
Enter a name and click *New Hero* again.
This time we see an error message! Why? We don't want that when we display a new (empty) hero.
Inspecting the element in the browser tools reveals that the *name* input box is no longer pristine.
Replacing the hero *did not restore the pristine state* of the control.
.l-sub-section
@ -559,26 +559,26 @@ figure.image-display
replacing the entire hero and clearing the `name` property programmatically.
Angular makes no assumptions and leaves the control in its current, dirty state.
:marked
We'll have to reset the form controls manually with a small trick.
We'll have to reset the form controls manually with a small trick.
We add an `active` flag to the component, initialized to `true`. When we add a new hero,
we toggle `active` false and then immediately back to true with a quick `setTimeout`.
+makeExample('forms/ts/app/hero-form.component.ts',
'new-hero',
+makeExample('forms/ts/app/hero-form.component.ts',
'new-hero',
'app/hero-form.component.ts (New Hero method - final)')(format=".")
:marked
Then we bind the form element to this `active` flag.
+makeExample('forms/ts/app/hero-form.component.html',
'form-active',
+makeExample('forms/ts/app/hero-form.component.html',
'form-active',
'app/hero-form.component.html (Form tag)')
:marked
With `NgIf` bound to the `active` flag,
With `NgIf` bound to the `active` flag,
clicking "New Hero" removes the form from the DOM and recreates it in a blink of an eye.
The re-created form is in a pristine state. The error message is hidden.
.l-sub-section
:marked
This is a temporary workaround while we await a proper form reset feature.
:marked
.l-main-section
:marked
## Submit the form with **ngSubmit**
@ -602,7 +602,7 @@ figure.image-display
:marked
### The NgForm directive
What `NgForm` directive? We didn't add an [NgForm](../api/common/index/NgForm-directive.html) directive!
Angular did. Angular creates and attaches an `NgForm` directive to the `<form>` tag automatically.
The `NgForm` directive supplements the `form` element with additional features.
@ -610,7 +610,7 @@ figure.image-display
and monitors their properties including their validity.
It also has its own `valid` property which is true only *if every contained
control* is valid.
:marked
Later in the template we bind the button's `disabled` property to the form's over-all validity via
the `heroForm` variable. Here's that bit of markup:
@ -686,7 +686,7 @@ figure.image-display
- A form component class with a `Component` decorator.
- The `ngSubmit` directive for handling the form submission.
- Template reference variables such as `#heroForm`, `#name` and `#power`.
- The `[(ngModel)]` syntax and a `name` attribute for two-way data binding, validation and change tracking.
- The `[(ngModel)]` syntax and a `name` attribute for two-way data binding, validation and change tracking.
- The reference variables `valid` property on input controls to check if a control is valid and show/hide error messages.
- Controlling the submit button's enabled state by binding to `NgForm` validity.
- Custom CSS classes that provide visual feedback to users about invalid controls.
@ -704,7 +704,7 @@ figure.image-display
.file hero-form.component.ts
.file main.ts
.file node_modules ...
.file typings ...
.file typings ...
.file index.html
.file package.json
.file tsconfig.json
@ -718,12 +718,12 @@ figure.image-display
forms/ts/app/hero.ts,
forms/ts/app/app.module.ts,
forms/ts/app/app.component.ts,
forms/ts/app/main.ts,
forms/ts/app/main.ts,
forms/ts/index.html,
forms/ts/forms.css`,
'final, final,,,,,',
`hero-form.component.ts,
hero-form.component.html,
hero-form.component.html,
hero.ts,
app.module.ts,
app.component.ts,

View File

@ -6,7 +6,7 @@ include ../_util-fns
In this chapter we learn to bind to those events using the Angular
event binding syntax.
<live-example>Run the live example</live-example>.
Run the <live-example></live-example>.
:marked
## Binding to user input events