parent
92f1690b73
commit
8e8963270b
|
@ -4,16 +4,16 @@
|
||||||
<!-- #docregion edit-div -->
|
<!-- #docregion edit-div -->
|
||||||
<div [hidden]="submitted">
|
<div [hidden]="submitted">
|
||||||
<h1>Hero Form</h1>
|
<h1>Hero Form</h1>
|
||||||
<!-- #docregion ng-submit -->
|
<!-- #docregion ngSubmit -->
|
||||||
<form (ng-submit)="onSubmit()" #hf="form">
|
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
|
||||||
<!-- #enddocregion ng-submit -->
|
<!-- #enddocregion ngSubmit -->
|
||||||
<!-- #enddocregion edit-div -->
|
<!-- #enddocregion edit-div -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<!-- #docregion name-with-error-msg -->
|
<!-- #docregion name-with-error-msg -->
|
||||||
<input type="text" class="form-control" required
|
<input type="text" class="form-control" required
|
||||||
[(ng-model)]="model.name"
|
[(ngModel)]="model.name"
|
||||||
ng-control="name" #name="form" >
|
ngControl="name" #name="ngForm" >
|
||||||
<div [hidden]="name.valid" class="alert alert-danger">
|
<div [hidden]="name.valid" class="alert alert-danger">
|
||||||
Name is required
|
Name is required
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,22 +23,22 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
[(ng-model)]="model.alterEgo"
|
[(ngModel)]="model.alterEgo"
|
||||||
ng-control="alterEgo" >
|
ngControl="alterEgo" >
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="power">Hero Power</label>
|
<label for="power">Hero Power</label>
|
||||||
<select class="form-control" required
|
<select class="form-control" required
|
||||||
[(ng-model)]="model.power"
|
[(ngModel)]="model.power"
|
||||||
ng-control="power" >
|
ngControl="power" >
|
||||||
<option *ng-for="#p of powers" [value]="p">{{p}}</option>
|
<option *ngFor="#p of powers" [value]="p">{{p}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- #docregion submit-button -->
|
<!-- #docregion submit-button -->
|
||||||
<button type="submit" class="btn btn-default"
|
<button type="submit" class="btn btn-default"
|
||||||
[disabled]="!hf.form.valid">Submit</button>
|
[disabled]="!heroForm.form.valid">Submit</button>
|
||||||
<!-- #enddocregion submit-button -->
|
<!-- #enddocregion submit-button -->
|
||||||
<!-- #docregion edit-div -->
|
<!-- #docregion edit-div -->
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -4,26 +4,26 @@
|
||||||
<form>
|
<form>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<!-- #docregion ng-control-1 -->
|
<!-- #docregion ngControl-1 -->
|
||||||
<input type="text" class="form-control" required
|
<input type="text" class="form-control" required
|
||||||
[(ng-model)]="model.name"
|
[(ngModel)]="model.name"
|
||||||
ng-control="name" >
|
ngControl="name" >
|
||||||
<!-- #enddocregion ng-control-1 -->
|
<!-- #enddocregion ngControl-1 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
[(ng-model)]="model.alterEgo"
|
[(ngModel)]="model.alterEgo"
|
||||||
ng-control="alterEgo" >
|
ngControl="alterEgo" >
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="power">Hero Power</label>
|
<label for="power">Hero Power</label>
|
||||||
<select class="form-control" required
|
<select class="form-control" required
|
||||||
[(ng-model)]="model.power"
|
[(ngModel)]="model.power"
|
||||||
ng-control="power" >
|
ngControl="power" >
|
||||||
<option *ng-for="#p of powers" [value]="p">{{p}}</option>
|
<option *ngFor="#p of powers" [value]="p">{{p}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -2,28 +2,28 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Hero Form</h1>
|
<h1>Hero Form</h1>
|
||||||
<form>
|
<form>
|
||||||
<!-- #docregion ng-model-2 -->
|
<!-- #docregion ngModel-2 -->
|
||||||
{{diagnostic}}
|
{{diagnostic}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<input type="text" class="form-control" required
|
<input type="text" class="form-control" required
|
||||||
[(ng-model)]="model.name" >
|
[(ngModel)]="model.name" >
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
[(ng-model)]="model.alterEgo">
|
[(ngModel)]="model.alterEgo">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="power">Hero Power</label>
|
<label for="power">Hero Power</label>
|
||||||
<select class="form-control" required
|
<select class="form-control" required
|
||||||
[(ng-model)]="model.power">
|
[(ngModel)]="model.power">
|
||||||
<option *ng-for="#p of powers" [value]="p">{{p}}</option>
|
<option *ngFor="#p of powers" [value]="p">{{p}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion ng-model-2 -->
|
<!-- #enddocregion ngModel-2 -->
|
||||||
|
|
||||||
<button type="submit" class="btn btn-default">Submit</button>
|
<button type="submit" class="btn btn-default">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
<form>
|
<form>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<!-- #docregion ng-model-1 -->
|
<!-- #docregion ngModel-1 -->
|
||||||
<input type="text" class="form-control" required
|
<input type="text" class="form-control" required
|
||||||
[(ng-model)]="model.name" >
|
[(ngModel)]="model.name" >
|
||||||
TODO: remove this: {{model.name}}
|
TODO: remove this: {{model.name}}
|
||||||
<!-- #enddocregion ng-model-1 -->
|
<!-- #enddocregion ngModel-1 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="power">Hero Power</label>
|
<label for="power">Hero Power</label>
|
||||||
<select class="form-control" required>
|
<select class="form-control" required>
|
||||||
<option *ng-for="#p of powers" [value]="p">{{p}}</option>
|
<option *ngFor="#p of powers" [value]="p">{{p}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion powers -->
|
<!-- #enddocregion powers -->
|
||||||
|
|
|
@ -4,25 +4,25 @@
|
||||||
<form>
|
<form>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<!-- #docregion ng-model-3 -->
|
<!-- #docregion ngModel-3 -->
|
||||||
<input type="text" class="form-control" required
|
<input type="text" class="form-control" required
|
||||||
[ng-model]="model.name"
|
[ngModel]="model.name"
|
||||||
(ng-model-change)="model.name = $event" >
|
(ngModel-change)="model.name = $event" >
|
||||||
TODO: remove this: {{model.name}}
|
TODO: remove this: {{model.name}}
|
||||||
<!-- #enddocregion ng-model-3 -->
|
<!-- #enddocregion ngModel-3 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
[(ng-model)]="model.alterEgo">
|
[(ngModel)]="model.alterEgo">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="power">Hero Power</label>
|
<label for="power">Hero Power</label>
|
||||||
<select class="form-control" required
|
<select class="form-control" required
|
||||||
[(ng-model)]="model.power">
|
[(ngModel)]="model.power">
|
||||||
<option *ng-for="#p of powers" [value]="p">{{p}}</option>
|
<option *ngFor="#p of powers" [value]="p">{{p}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -4,27 +4,27 @@
|
||||||
<form>
|
<form>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<!-- #docregion ng-control-2 -->
|
<!-- #docregion ngControl-2 -->
|
||||||
<input type="text" class="form-control" required
|
<input type="text" class="form-control" required
|
||||||
[(ng-model)]="model.name"
|
[(ngModel)]="model.name"
|
||||||
ng-control="name" #spy >
|
ngControl="name" #spy >
|
||||||
TODO: remove this: {{spy.className}}
|
TODO: remove this: {{spy.className}}
|
||||||
<!-- #enddocregion ng-control-2 -->
|
<!-- #enddocregion ngControl-2 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="alterEgo">Alter Ego</label>
|
<label for="alterEgo">Alter Ego</label>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
[(ng-model)]="model.alterEgo"
|
[(ngModel)]="model.alterEgo"
|
||||||
ng-control="alterEgo" >
|
ngControl="alterEgo" >
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="power">Hero Power</label>
|
<label for="power">Hero Power</label>
|
||||||
<select class="form-control" required
|
<select class="form-control" required
|
||||||
[(ng-model)]="model.power"
|
[(ngModel)]="model.power"
|
||||||
ng-control="power" >
|
ngControl="power" >
|
||||||
<option *ng-for="#p of powers" [value]="p">{{p}}</option>
|
<option *ngFor="#p of powers" [value]="p">{{p}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ name: hero_form
|
||||||
description: Form example
|
description: Form example
|
||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
dependencies:
|
dependencies:
|
||||||
angular2: 2.0.0-alpha.47
|
angular2: 2.0.0-alpha.52
|
||||||
browser: ^0.10.0
|
browser: ^0.10.0
|
||||||
transformers:
|
transformers:
|
||||||
- angular2:
|
- angular2:
|
||||||
|
|
|
@ -20,11 +20,11 @@ include ../../../../_includes/_util-fns
|
||||||
|
|
||||||
- How to build an Angular form with a component and template
|
- How to build an Angular form with a component and template
|
||||||
|
|
||||||
- The `ng-model` two-way data binding syntax for reading and writing values to input controls
|
- The `ngModel` two-way data binding syntax for reading and writing values to input controls
|
||||||
|
|
||||||
- The `ng-control` directive to track the change state and validity of form controls
|
- The `ngControl` directive to track the change state and validity of form controls
|
||||||
|
|
||||||
- The special CSS classes that `ng-control` adds to form controls and how to use them to provide strong visual feedback
|
- The special CSS classes that `ngControl` adds to form controls and how to use them to provide strong visual feedback
|
||||||
|
|
||||||
- How to display validation errors to users and enable/disable form controls
|
- How to display validation errors to users and enable/disable form controls
|
||||||
|
|
||||||
|
@ -79,11 +79,11 @@ figure.image-display
|
||||||
1. Create the `Hero` model class.
|
1. Create the `Hero` model class.
|
||||||
1. Create the component that controls the form.
|
1. Create the component that controls the form.
|
||||||
1. Create a template with the initial form layout.
|
1. Create a template with the initial form layout.
|
||||||
1. Add the **ng-model** directive to each form input control.
|
1. Add the **ngModel** directive to each form input control.
|
||||||
1. Add the **ng-control** directive to each form input control.
|
1. Add the **ngControl** directive to each form input control.
|
||||||
1. Add custom CSS to provide visual feedback.
|
1. Add custom CSS to provide visual feedback.
|
||||||
1. Show and hide validation error messages.
|
1. Show and hide validation error messages.
|
||||||
1. Handle form submission with **ng-submit**.
|
1. Handle form submission with **ngSubmit**.
|
||||||
1. Change the form's display after submission.
|
1. Change the form's display after submission.
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
|
@ -236,7 +236,7 @@ figure.image-display
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Add powers with ***ng-for**
|
## Add powers with ***ngFor**
|
||||||
Our hero must choose one super power from a fixed list of Agency-approved powers.
|
Our hero must choose one super power from a fixed list of Agency-approved powers.
|
||||||
We maintain that list internally (in `HeroFormComponent`).
|
We maintain that list internally (in `HeroFormComponent`).
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ figure.image-display
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Two-way data binding with ***ng-model**
|
## Two-way data binding with ***ngModel**
|
||||||
Running the app right now would be disappointing.
|
Running the app right now would be disappointing.
|
||||||
|
|
||||||
figure.image-display
|
figure.image-display
|
||||||
|
@ -275,7 +275,7 @@ figure.image-display
|
||||||
|
|
||||||
Find the `<input>` tag for Name and update it like this:
|
Find the `<input>` tag for Name and update it like this:
|
||||||
|
|
||||||
+makeExample('forms/dart/lib/hero_form_component_ngmodel_ngfor.html', 'ng-model-1', 'lib/hero_form_component.html (excerpt)')(format=".")
|
+makeExample('forms/dart/lib/hero_form_component_ngmodel_ngfor.html', 'ngModel-1', 'lib/hero_form_component.html (excerpt)')(format=".")
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -284,32 +284,32 @@ figure.image-display
|
||||||
We left ourselves a note to throw it way when we're done.
|
We left ourselves a note to throw it way when we're done.
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Focus on the binding syntax: `[(ng-model)]="..."`.
|
Focus on the binding syntax: `[(ngModel)]="..."`.
|
||||||
|
|
||||||
If we ran the app right now and started typing in the Name input box,
|
If we ran the app right now and started typing in the Name input box,
|
||||||
adding and deleting characters, we'd see them appearing and disappearing
|
adding and deleting characters, we'd see them appearing and disappearing
|
||||||
from the interpolated text.
|
from the interpolated text.
|
||||||
At some point it might look like this.
|
At some point it might look like this.
|
||||||
figure.image-display
|
figure.image-display
|
||||||
img(src="/resources/images/devguide/forms/ng-model-in-action.png" width="400px" alt="ng-model in action")
|
img(src="/resources/images/devguide/forms/ng-model-in-action.png" width="400px" alt="ngModel in action")
|
||||||
:marked
|
:marked
|
||||||
The diagnostic is evidence that values really are flowing from the input box to the model and
|
The diagnostic is evidence that values really are flowing from the input box to the model and
|
||||||
back again. **That's two-way data binding!**
|
back again. **That's two-way data binding!**
|
||||||
|
|
||||||
Let's add similar `[(ng-model)]` bindings to Alter Ego and Hero Power.
|
Let's add similar `[(ngModel)]` bindings to Alter Ego and Hero Power.
|
||||||
We'll ditch the input box binding message
|
We'll ditch the input box binding message
|
||||||
and add a new binding at the top to the component's `diagnostic` property.
|
and add a new binding at the top to the component's `diagnostic` property.
|
||||||
Then we can confirm that two-way data binding works *for the entire Hero model*.
|
Then we can confirm that two-way data binding works *for the entire Hero model*.
|
||||||
|
|
||||||
After revision, the core of the form should have three `[(ng-model)]` bindings that
|
After revision, the core of the form should have three `[(ngModel)]` bindings that
|
||||||
look much like this:
|
look much like this:
|
||||||
|
|
||||||
+makeExample('forms/dart/lib/hero_form_component_ngmodel2.html', 'ng-model-2', 'lib/hero_form_component.html (excerpt)')(format=".")
|
+makeExample('forms/dart/lib/hero_form_component_ngmodel2.html', 'ngModel-2', 'lib/hero_form_component.html (excerpt)')(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
If we ran the app right now and changed every Hero model property, the form might look like this:
|
If we ran the app right now and changed every Hero model property, the form might look like this:
|
||||||
figure.image-display
|
figure.image-display
|
||||||
img(src="images/ng-model-in-action-2.png" width="500px" alt="ng-model in super action")
|
img(src="images/ng-model-in-action-2.png" width="500px" alt="ngModel in super action")
|
||||||
:marked
|
:marked
|
||||||
The diagnostic near the top of the form
|
The diagnostic near the top of the form
|
||||||
confirms that our changes to the values are reflected in the model.
|
confirms that our changes to the values are reflected in the model.
|
||||||
|
@ -318,9 +318,9 @@ figure.image-display
|
||||||
|
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
h3 Inside [(ng-model)]
|
h3 Inside [(ngModel)]
|
||||||
:marked
|
:marked
|
||||||
*This section is an optional deep dive into [(ng-model)]. Not interested? Skip ahead!*
|
*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.
|
The punctuation in the binding syntax, <span style="font-family:courier"><b>[()]</b></span>, is a good clue to what's going on.
|
||||||
|
|
||||||
|
@ -337,22 +337,22 @@ figure.image-display
|
||||||
|
|
||||||
In fact, we can break the `NgModel` binding into its two separate modes
|
In fact, we can break the `NgModel` binding into its two separate modes
|
||||||
as in this rewrite of the Name `<input>` binding:
|
as in this rewrite of the Name `<input>` binding:
|
||||||
+makeExample('forms/dart/lib/hero_form_component_ngmodelchange.html', 'ng-model-3')(format=".")
|
+makeExample('forms/dart/lib/hero_form_component_ngmodelchange.html', 'ngModel-3')(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
<br>The property binding should feel familiar. The event binding might seem strange.
|
<br>The property binding should feel familiar. The event binding might seem strange.
|
||||||
|
|
||||||
The name `ng-model-change` specifies an event property of the `NgModel` directive.
|
The name `ngModel-change` specifies an event property of the `NgModel` directive.
|
||||||
When Angular sees a binding target in the form <span style="font-family:courier">[(abc)]</span>,
|
When Angular sees a binding target in the form <span style="font-family:courier">[(abc)]</span>,
|
||||||
it expects the `abc` directive to have an `abc` input property and an `abc-change` output property.
|
it expects the `abc` directive to have an `abc` input property and an `abc-change` output property.
|
||||||
|
|
||||||
The other oddity is the template expression, `model.name = $event`.
|
The other oddity is the template expression, `model.name = $event`.
|
||||||
We're used to seeing an `$event` object coming from a DOM event.
|
We're used to seeing an `$event` object coming from a DOM event.
|
||||||
The `ng-model-change` property doesn't produce a DOM event; it's an Angular `EventEmitter`
|
The `ngModel-change` property doesn't produce a DOM event; it's an Angular `EventEmitter`
|
||||||
property that returns the input box value when it fires—which is precisely what
|
property that returns the input box value when it fires—which is precisely what
|
||||||
we should assign to the model's `name` property.
|
we should assign to the model's `name` property.
|
||||||
|
|
||||||
Nice to know but is it practical? `[(ng-model)]` is usually what we want, but
|
Nice to know but is it practical? `[(ngModel)]` is usually what we want, but
|
||||||
we might split the binding when the event handling has to do something special
|
we might split the binding when the event handling has to do something special
|
||||||
such as debounce or throttle the keystrokes.
|
such as debounce or throttle the keystrokes.
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ figure.image-display
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Track change-state and validity with **ng-control**
|
## Track change-state and validity with **ngControl**
|
||||||
|
|
||||||
A form isn't just about data binding. We'd also like to know the state of the controls on our form.
|
A form isn't just about data binding. We'd also like to know the state of the controls on our form.
|
||||||
The `NgControl` directive keeps track of control state for us.
|
The `NgControl` directive keeps track of control state for us.
|
||||||
|
@ -384,15 +384,15 @@ figure.image-display
|
||||||
control and make messages appear or disappear.
|
control and make messages appear or disappear.
|
||||||
|
|
||||||
We'll explore those effects soon. Right now
|
We'll explore those effects soon. Right now
|
||||||
let's **add `ng-control`to all three form controls**,
|
let's **add `ngControl`to all three form controls**,
|
||||||
starting with the Name input box.
|
starting with the Name input box.
|
||||||
+makeExample('forms/dart/lib/hero_form_component_ngcontrol.html', 'ng-control-1', 'lib/hero_form_component.html (excerpt)')(format=".")
|
+makeExample('forms/dart/lib/hero_form_component_ngcontrol.html', 'ngControl-1', 'lib/hero_form_component.html (excerpt)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Be sure to assign a unique name to each `ng-control` directive.
|
Be sure to assign a unique name to each `ngControl` directive.
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
Angular registers controls under their `ng-control` names
|
Angular registers controls under their `ngControl` names
|
||||||
with the `NgForm` directive.
|
with the `NgForm` directive.
|
||||||
We didn't add the `NgForm` directive explicitly but it's here;
|
We didn't add the `NgForm` directive explicitly but it's here;
|
||||||
we'll talk about it [later in this chapter](#ng-form).
|
we'll talk about it [later in this chapter](#ng-form).
|
||||||
|
@ -429,7 +429,7 @@ figure.image-display
|
||||||
named **spy**
|
named **spy**
|
||||||
to the Name `<input>` tag and use the spy to display those classes.
|
to the Name `<input>` tag and use the spy to display those classes.
|
||||||
|
|
||||||
+makeExample('forms/dart/lib/hero_form_component_spy.html', 'ng-control-2')(format=".")
|
+makeExample('forms/dart/lib/hero_form_component_spy.html', 'ngControl-2')(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Now run the app, and look at the Name input box.
|
Now run the app, and look at the Name input box.
|
||||||
|
@ -442,8 +442,8 @@ figure.image-display
|
||||||
|
|
||||||
The classes are displayed as follows:
|
The classes are displayed as follows:
|
||||||
|
|
||||||
1. `form-control ng-untouched ng-pristine ng-valid` (initial state)
|
1. `form-control ng-untouched ng-valid ng-pristine` (initial state)
|
||||||
1. `form-control ng-pristine ng-valid ng-touched` (after clicking)
|
1. `form-control ng-valid ng-pristine ng-touched` (after clicking)
|
||||||
1. `form-control ng-valid ng-touched ng-dirty` (after changing)
|
1. `form-control ng-valid ng-touched ng-dirty` (after changing)
|
||||||
1. `form-control ng-touched ng-dirty ng-invalid` (after erasing)
|
1. `form-control ng-touched ng-dirty ng-invalid` (after erasing)
|
||||||
|
|
||||||
|
@ -498,11 +498,11 @@ figure.image-display
|
||||||
+makeExample('forms/dart/lib/hero_form_component.html', 'name-with-error-msg', 'lib/hero_form_component.html (excerpt)', stylePattern)(format=".")
|
+makeExample('forms/dart/lib/hero_form_component.html', 'name-with-error-msg', 'lib/hero_form_component.html (excerpt)', stylePattern)(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
We initialized the template local variable with the string "form"
|
We initialized the template local variable with the string "ngForm"
|
||||||
(`#name="form"`).
|
(`#name="ngForm"`).
|
||||||
|
|
||||||
Angular recognizes that syntax and sets the `name` variable
|
Angular recognizes that syntax and sets the `name` variable
|
||||||
to the `Control` object identified by the `ng-control` directive that,
|
to the `Control` object identified by the `ngControl` directive that,
|
||||||
not coincidentally, we called "name".
|
not coincidentally, we called "name".
|
||||||
|
|
||||||
We bind the `Control` object's `valid` property to the element's `hidden` property.
|
We bind the `Control` object's `valid` property to the element's `hidden` property.
|
||||||
|
@ -513,14 +513,14 @@ figure.image-display
|
||||||
h3 The NgForm directive
|
h3 The NgForm directive
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Recall from the previous section that `ng-control` registered this input box with the
|
Recall from the previous section that `ngControl` registered this input box with the
|
||||||
`NgForm` directive as "name".
|
`NgForm` directive as "name".
|
||||||
|
|
||||||
We didn't add the `NgForm`<!-- TODO: link to (../api/core/NgForm-class.html) --> directive explicitly.
|
We didn't add the `NgForm`<!-- TODO: link to (../api/core/NgForm-class.html) --> directive explicitly.
|
||||||
Angular added it surreptitiously, wrapping it around the `<form>` element.
|
Angular added it surreptitiously, wrapping it around the `<form>` element.
|
||||||
|
|
||||||
The `NgForm` directive supplements the `<form>` element with additional features.
|
The `NgForm` directive supplements the `<form>` element with additional features.
|
||||||
It collects controls (elements identified by an `ng-control` directive)
|
It collects controls (elements identified by an `ngControl` directive)
|
||||||
and monitors their properties including their validity.
|
and monitors their properties including their validity.
|
||||||
It has its own `valid` property, which is true only if every contained
|
It has its own `valid` property, which is true only if every contained
|
||||||
control is valid.
|
control is valid.
|
||||||
|
@ -539,7 +539,7 @@ figure.image-display
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Submit the form with **ng-submit**
|
## Submit the form with **ngSubmit**
|
||||||
The user should be able to submit this form after filling it in.
|
The user should be able to submit this form after filling it in.
|
||||||
The Submit button at the bottom of the form
|
The Submit button at the bottom of the form
|
||||||
does nothing on its own, but it will
|
does nothing on its own, but it will
|
||||||
|
@ -548,18 +548,18 @@ figure.image-display
|
||||||
A "form submit" is meaningless at the moment. To make it meaningful,
|
A "form submit" is meaningless at the moment. To make it meaningful,
|
||||||
we'll update the `<form>` tag with another Angular directive, `NgSubmit`,
|
we'll update the `<form>` tag with another Angular directive, `NgSubmit`,
|
||||||
and bind it to the `HeroFormComponent.onSubmit()` method:
|
and bind it to the `HeroFormComponent.onSubmit()` method:
|
||||||
+makeExample('forms/dart/lib/hero_form_component.html', 'ng-submit')(format=".")
|
+makeExample('forms/dart/lib/hero_form_component.html', 'ngSubmit')(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
We slipped in something extra there at the end! We defined a
|
We slipped in something extra there at the end! We defined a
|
||||||
template local variable, **`#hf`**, and initialized it with the value "form".
|
template local variable, **`#heroForm`**, and initialized it with the value "ngForm".
|
||||||
|
|
||||||
The variable `hf` is now a handle to the `NgForm` as we [discussed earlier](#ng-form)
|
The variable `heroForm` is now a handle to the `NgForm` as we [discussed earlier](#ng-form)
|
||||||
with respect to `ng-control`, although this time we have a reference to the form
|
with respect to `ngControl`, although this time we have a reference to the form
|
||||||
rather than a control.
|
rather than a control.
|
||||||
|
|
||||||
We'll bind the form's overall validity via
|
We'll bind the form's overall validity via
|
||||||
the `hf` variable to the button's `disabled` property
|
the `heroForm` variable to the button's `disabled` property
|
||||||
using an event binding. Here's the code:
|
using an event binding. Here's the code:
|
||||||
+makeExample('forms/dart/lib/hero_form_component.html', 'submit-button')(format=".")
|
+makeExample('forms/dart/lib/hero_form_component.html', 'submit-button')(format=".")
|
||||||
:marked
|
:marked
|
||||||
|
@ -631,10 +631,10 @@ figure.image-display
|
||||||
|
|
||||||
- An Angular HTML form template.
|
- An Angular HTML form template.
|
||||||
- A form component class with a `Component` decorator.
|
- A form component class with a `Component` decorator.
|
||||||
- The `ng-submit` directive for handling the form submission.
|
- The `ngSubmit` directive for handling the form submission.
|
||||||
- Template local variables such as `#hf`, `#name`, `#alter-ego`, and `#power`.
|
- Template local variables such as `#heroForm`, `#name`, `#p`, and `#spy`.
|
||||||
- The `ng-model` directive for two-way data binding.
|
- The `ngModel` directive for two-way data binding.
|
||||||
- The `ng-control` directive for validation and form element change tracking.
|
- The `ngControl` directive for validation and form element change tracking.
|
||||||
- The local variable’s `valid` property on input controls to check if a control is valid and show/hide error messages.
|
- The local variable’s `valid` property on input controls to check if a control is valid and show/hide error messages.
|
||||||
- Property binding to disable the submit button when the form is invalid.
|
- Property binding to disable the submit button when the form is invalid.
|
||||||
- Custom CSS classes that provide visual feedback to users about required invalid controls.
|
- Custom CSS classes that provide visual feedback to users about required invalid controls.
|
||||||
|
|
Loading…
Reference in New Issue