Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 4c168e3

Browse files
committed
docs(guide): copyedit user-input
1 parent 253ad57 commit 4c168e3

File tree

1 file changed

+70
-65
lines changed

1 file changed

+70
-65
lines changed
Lines changed: 70 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
include ../../../../_includes/_util-fns
22

33
:marked
4-
When the user clicks a link, pushes a button, or types on the keyboard
4+
When the user clicks a link, pushes a button, or enters text
55
we want to know about it. These user actions all raise DOM events.
6-
In this chapter we learn to bind to those events using the Angular Event Binding syntax.
6+
In this chapter we learn to bind to those events using the Angular
7+
event binding syntax.
78

8-
[Live Example](/resources/live-examples/user-input/ts/plnkr.html).
9+
[Run the live example](/resources/live-examples/user-input/ts/plnkr.html)
910

1011
:marked
11-
## Binding to User Input Events
12+
## Binding to user input events
1213

13-
We can listen to [any DOM event](https://developer.mozilla.org/en-US/docs/Web/Events)
14-
with an [Angular Event Binding](./template-syntax.html#event-binding).
14+
We can use [Angular event bindings](./template-syntax.html#event-binding)
15+
to respond to [any DOM event](https://developer.mozilla.org/en-US/docs/Web/Events).
1516

1617
The syntax is simple. We assign a template expression to the DOM event name, surrounded in parentheses.
17-
A click Event Binding makes for a quick illustration.
18+
As an example, here's an event binding that implements a click handler:
1819
+makeExample('user-input/ts/app/click-me.component.ts', 'click-me-button')(format=".", language="html")
1920

2021
<a id="click"></a>
2122
:marked
2223
The `(click)` to the left of the equal sign identifies the button's click event as the **target of the binding**.
23-
The text within quotes on the right is the "**template expression**" in which we
24+
The text within quotes on the right is the **template expression** in which we
2425
respond to the click event by calling the component's `onClickMe` method. A [template expression](./template-syntax.html#template-expressions) is a subset
2526
of JavaScript with a few added tricks.
2627

@@ -29,37 +30,37 @@ include ../../../../_includes/_util-fns
2930
That object is usually the Angular component that controls the template ... which it definitely is
3031
in this case because that snippet of HTML belongs to the following component:
3132

32-
+makeExample('user-input/ts/app/click-me.component.ts', 'click-me-component', 'app/click-me.component.ts')
33+
+makeExample('user-input/ts/app/click-me.component.ts', 'click-me-component', 'app/click-me.component.ts')(format=".")
3334
:marked
34-
The `onClickMe` in the template refers to the `onClickMe` method of the component.
3535
When the user clicks the button, Angular calls the component's `onClickMe` method.
3636

3737
.l-main-section
3838
:marked
3939
## Get user input from the $event object
40-
We can bind to all kinds of events. Let's bind to the "keyup" event of an input box and replay
40+
We can bind to all kinds of events. Let's bind to the keyup event of an input box and replay
4141
what the user types back onto the screen.
4242

4343
This time we'll (1) listen to an event and (2) grab the user's input.
44-
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-1-template', 'app/keyup.components.ts (template v.1)')
44+
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-1-template', 'app/keyup.components.ts (template v.1)')(format=".")
4545
:marked
46-
Angular makes an event object available in the **`$event`** variable
46+
Angular makes an event object available in the **`$event`** variable,
4747
which we pass to the component's `onKey()` method.
4848
The user data we want is in that variable somewhere.
49-
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-1-class-no-type', 'app/keyup.components.ts (class v.1)')
49+
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-1-class-no-type', 'app/keyup.components.ts (class v.1)')(format=".")
5050
:marked
5151
The shape of the `$event` object is determined by whatever raises the event.
52-
The `keyup` event comes from the DOM so `$event` must be a [standard DOM event object](https://developer.mozilla.org/en-US/docs/Web/API/Event).
53-
The `$event.target` gives us the
54-
[`HTMLInputElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement) which
55-
has a `value` property and that's where we find our user input data.
52+
The `keyup` event comes from the DOM, so `$event` must be a [standard DOM event object](https://developer.mozilla.org/en-US/docs/Web/API/Event).
53+
The `$event.target` gives us an
54+
[`HTMLInputElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement), which
55+
has a `value` property that contains our user input data.
5656

57-
We had this in mind when we passed `$event` to our `onKey()` component method. This is where we extract the user's input and
58-
concatenate it to the previous user data that we're accumulating in the component's `values` property.
57+
The `onKey()` component method is where we extract the user's input
58+
from the event object, adding that input to the list of user data that we're accumulating in the component's `values` property.
5959
We then use [interpolation](./template-syntax.html#interpolation)
6060
to display the accumulating `values` property back on screen.
6161

62-
Enter the letters "abc", backspace to remove them, and we should see:
62+
Enter the letters "abc", and then backspace to remove them.
63+
Here's what the UI displays:
6364
code-example().
6465
a | ab | abc | ab | a | |
6566
figure.image-display
@@ -68,10 +69,10 @@ figure.image-display
6869
<a id="keyup1"></a>
6970
.l-sub-section
7071
:marked
71-
We cast the `$event` as an `any` type which means we've abandoned strong typing
72+
We cast the `$event` as an `any` type, which means we've abandoned strong typing
7273
to simplify our code. We generally prefer the strong typing that TypeScript affords.
7374
We can rewrite the method, casting to HTML DOM objects like this.
74-
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-1-class', 'app/keyup.components.ts (class v.1 - strongly typed )')
75+
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-1-class', 'app/keyup.components.ts (class v.1 - strongly typed )')(format=".")
7576
:marked
7677
<br>Strong typing reveals a serious problem with passing a DOM event into the method:
7778
too much awareness of template details, too little separation of concerns.
@@ -88,17 +89,19 @@ figure.image-display
8889
These variables grant us direct access to an element.
8990
We declare a local template variable by preceding an identifier with a hash/pound character (#).
9091

91-
Let's demonstrate with a clever keystroke loopback in an ultra-simple template.
92-
+makeExample('user-input/ts/app/loop-back.component.ts', 'loop-back-component', 'app/loop-back.component.ts')
92+
Here's an example of using a local template variable
93+
to implement a clever keystroke loopback in an ultra-simple template.
94+
+makeExample('user-input/ts/app/loop-back.component.ts', 'loop-back-component', 'app/loop-back.component.ts')(format=".")
9395
:marked
9496
We've declared a template local variable named `box` on the `<input>` element.
95-
The `box` variable is a reference to the `<input>` element itself which means we can
97+
The `box` variable is a reference to the `<input>` element itself, which means we can
9698
grab the input element's `value` and display it
9799
with interpolation between `<p>` tags.
98100

99-
The template is completely self contained. It doesn't bind to the component which does nothing.
101+
The template is completely self contained. It doesn't bind to the component,
102+
and the component does nothing.
100103

101-
Type in the input box and watch the display update with each keystroke. *Voila!*
104+
Type in the input box, and watch the display update with each keystroke. *Voila!*
102105

103106
figure.image-display
104107
img(src='/resources/images/devguide/user-input/keyup-loop-back-anim.gif' alt="loop back")
@@ -114,9 +117,9 @@ figure.image-display
114117
That is all it takes to keep Angular happy. We said it would be clever!
115118
:marked
116119
That local template variable is intriguing. It's clearly easier to get to the textbox with that
117-
variable than to go through the `$event` object. Maybe we can re-write our previous
118-
"key-up" example using the variable to acquire the user's input. Let's give it a try.
119-
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-2' ,'app/keyup.components.ts (v2)')
120+
variable than to go through the `$event` object. Maybe we can rewrite our previous
121+
keyup example so that it uses the variable to get the user's input. Let's give it a try.
122+
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-2' ,'app/keyup.components.ts (v2)')(format=".")
120123
:marked
121124
That sure seems easier.
122125
An especially nice aspect of this approach is that our component code gets clean data values from the view.
@@ -127,17 +130,17 @@ figure.image-display
127130
:marked
128131
## Key event filtering (with `key.enter`)
129132
Perhaps we don't care about every keystroke.
130-
We're only interested in the input box value when the user hits the "Enter" key. We'd like to ignore all other keys.
131-
When we bind to the `(keyup)` event, our event handling expression hears *every key stroke*.
132-
We could filter the keys first, examining every `$event.keyCode`, and update the `values` property only if the key is "Enter".
133+
Maybe we're only interested in the input box value when the user presses Enter, and we'd like to ignore all other keys.
134+
When we bind to the `(keyup)` event, our event handling expression hears *every keystroke*.
135+
We could filter the keys first, examining every `$event.keyCode`, and update the `values` property only if the key is Enter.
133136

134137
Angular can filter the key events for us. Angular has a special syntax for keyboard events.
135-
We can listen for just the "Enter" key by binding to Angular's `keyup.enter` pseudo-event.
138+
We can listen for just the Enter key by binding to Angular's `keyup.enter` pseudo-event.
136139

137-
Only then do we update the component's `values` property ...
138-
inside the event expression rather than in the component ...
139-
because we *can* ... even if it is a dubious practice.
140-
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-3' ,'app/keyup.components.ts (v3)')
140+
Only then do we update the component's `values` property. (In this example,
141+
the update happens inside the event expression. A better practice
142+
would be to put the update code in the component.)
143+
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-3' ,'app/keyup.components.ts (v3)')(format=".")
141144
:marked
142145
Here's how it works.
143146
figure.image-display
@@ -148,12 +151,12 @@ figure.image-display
148151
## On blur
149152

150153
Our previous example won't transfer the current state of the input box if the user mouses away and clicks
151-
elsewhere on the page. We only update the component's `values` property when the user presses "Enter"
152-
inside the input box.
154+
elsewhere on the page. We update the component's `values` property only when the user presses Enter
155+
while the focus is inside the input box.
153156

154157
Let's fix that by listening to the input box's blur event as well.
155158

156-
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-4' ,'app/keyup.components.ts (v4)')
159+
+makeExample('user-input/ts/app/keyup.components.ts', 'key-up-component-4' ,'app/keyup.components.ts (v4)')(format=".")
157160

158161
.l-main-section
159162
:marked
@@ -162,54 +165,56 @@ figure.image-display
162165
We've acquired a small arsenal of event binding techniques in this chapter.
163166

164167
Let's put it all together in a micro-app
165-
that can display a list of heroes and add new heroes to that list
166-
by typing in the input box and hitting "Enter", clicking "Add", or clicking
167-
elsewhere on the page.
168+
that can display a list of heroes and add new heroes to that list.
169+
The user can add a hero by first typing in the input box and then
170+
pressing Enter, clicking the Add button, or clicking elsewhere on the page.
168171

169172
figure.image-display
170173
img(src='/resources/images/devguide/user-input/little-tour-anim.gif' alt="Little Tour of Heroes")
171174
:marked
172175
Below is the "Little Tour of Heroes" component.
173176
We'll call out the highlights after we bask briefly in its minimalist glory.
174177

175-
+makeExample('user-input/ts/app/little-tour.component.ts', 'little-tour', 'app/little-tour.component.ts')
178+
+makeExample('user-input/ts/app/little-tour.component.ts', 'little-tour', 'app/little-tour.component.ts')(format=".")
176179
:marked
177180
We've seen almost everything here before. A few things are new or bear repeating.
178181

179-
### *newHero* template variable
182+
### Use template variables to refer to elements
180183

181-
The *newHero* template variable refers to the `<input>` element.
184+
The `newHero` template variable refers to the `<input>` element.
185+
We can use `newHero` from any sibling or child of the `<input>` element.
182186

183-
We can access `newHero` from any sibling or child of the `<input>` element.
184-
When the user clicks the button, we don't need a fancy CSS selector to
185-
track down the textbox and extract its value.
187+
Getting the element from a template variable makes the button click handler
188+
simpler. Without the variable, we'd have to use a fancy CSS selector
189+
to find the input element.
186190

187-
### Extract the input box *value*
188-
We could have passed the `newHero` into the component's `addHero()` method.
191+
### Pass values, not elements
192+
193+
We could have passed the `newHero` into the component's `addHero` method.
189194

190195
But that would require `addHero` to pick its way through the `<input>` DOM element,
191-
something we learned to dislike in our first try at a [*KeyupComponent*](#keyup1).
196+
something we learned to dislike in our first try at a [keyup component](#keyup1).
192197

193-
Instead, we grab the input box *value* and pass *that* to `addHero()`.
194-
The component knows nothing about HTML or DOM which is the way we like it.
198+
Instead, we grab the input box *value* and pass *that* to `addHero`.
199+
The component knows nothing about HTML or the DOM, which is the way we like it.
195200

196-
### Don't let template expressions be complex
201+
### Keep template expressions simple
197202
We bound `(blur)` to *two* JavaScript statements.
198203

199-
We like the first one that calls `addHero`.
200-
We do not like the second one that assigns an empty string to the input box value.
204+
We like the first one, which calls `addHero`.
205+
We do not like the second one, which assigns an empty string to the input box value.
201206

202-
We did it for a good reason. We have to clear the input box after adding the new hero to the list.
203-
The component has no way to do that itself &mdash; because it has no access to the
207+
The second statement exists for a good reason. We have to clear the input box after adding the new hero to the list.
208+
The component has no way to do that itself because it has no access to the
204209
input box (our design choice).
205210

206-
Although it *works*, we are rightly wary of JavaScript in HTML.
211+
Although the example *works*, we are rightly wary of JavaScript in HTML.
207212
Template expressions are powerful. We're supposed to use them responsibly.
208213
Complex JavaScript in HTML is irresponsible.
209214

210215
Should we reconsider our reluctance to pass the input box into the component?
211216

212-
There should be a better third way. And there is as we'll see when we learn about `NgModel` in the [Forms](forms.html) chapter.
217+
There should be a better third way. And there is, as we'll see when we learn about `NgModel` in the [Forms](forms.html) chapter.
213218
.l-main-section
214219
:marked
215220
## Source code
@@ -228,12 +233,12 @@ figure.image-display
228233

229234
.l-main-section
230235
:marked
231-
## Next Steps
236+
## Summary
232237

233238
We've mastered the basic primitives for responding to user input and gestures.
234239
As powerful as these primitives are, they are a bit clumsy for handling
235240
large amounts of user input. We're operating down at the low level of events when
236241
we should be writing two-way bindings between data entry fields and model properties.
237242

238-
Angular has a two-way binding called `NgModel` and we learn about it
243+
Angular has a two-way binding called `NgModel`, which we'll learn about
239244
in the `Forms` chapter.

0 commit comments

Comments
 (0)