Skip to content

Commit 493f0fb

Browse files
committed
docs(docs-infra): traducción de guide/user-input.md #191
1 parent eac35a6 commit 493f0fb

File tree

2 files changed

+460
-132
lines changed

2 files changed

+460
-132
lines changed

aio/content/guide/user-input.en.md

+328
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
# User input
2+
3+
User actions such as clicking a link, pushing a button, and entering
4+
text raise DOM events.
5+
This page explains how to bind those events to component event handlers using the Angular
6+
event binding syntax.
7+
8+
Run the <live-example></live-example>.
9+
10+
11+
## Binding to user input events
12+
13+
You can use [Angular event bindings](guide/event-binding)
14+
to respond to any [DOM event](https://developer.mozilla.org/en-US/docs/Web/Events).
15+
Many DOM events are triggered by user input. Binding to these events provides a way to
16+
get input from the user.
17+
18+
To bind to a DOM event, surround the DOM event name in parentheses and assign a quoted
19+
[template statement](guide/template-statements) to it.
20+
21+
The following example shows an event binding that implements a click handler:
22+
23+
<code-example path="user-input/src/app/click-me.component.ts" region="click-me-button" header="src/app/click-me.component.ts"></code-example>
24+
25+
{@a click}
26+
27+
The `(click)` to the left of the equals sign identifies the button's click event as the **target of the binding**.
28+
The text in quotes to the right of the equals sign
29+
is the **template statement**, which responds
30+
to the click event by calling the component's `onClickMe` method.
31+
32+
When writing a binding, be aware of a template statement's **execution context**.
33+
The identifiers in a template statement belong to a specific context object,
34+
usually the Angular component controlling the template.
35+
The example above shows a single line of HTML, but that HTML belongs to a larger component:
36+
37+
38+
<code-example path="user-input/src/app/click-me.component.ts" region="click-me-component" header="src/app/click-me.component.ts"></code-example>
39+
40+
41+
42+
When the user clicks the button, Angular calls the `onClickMe` method from `ClickMeComponent`.
43+
44+
45+
46+
## Get user input from the $event object
47+
DOM events carry a payload of information that may be useful to the component.
48+
This section shows how to bind to the `keyup` event of an input box to get the user's input after each keystroke.
49+
50+
The following code listens to the `keyup` event and passes the entire event payload (`$event`) to the component event handler.
51+
52+
<code-example path="user-input/src/app/keyup.components.ts" region="key-up-component-1-template" header="src/app/keyup.components.ts (template v.1)"></code-example>
53+
54+
55+
56+
When a user presses and releases a key, the `keyup` event occurs, and Angular provides a corresponding
57+
DOM event object in the `$event` variable which this code passes as a parameter to the component's `onKey()` method.
58+
59+
<code-example path="user-input/src/app/keyup.components.ts" region="key-up-component-1-class-no-type" header="src/app/keyup.components.ts (class v.1)"></code-example>
60+
61+
62+
63+
The properties of an `$event` object vary depending on the type of DOM event. For example,
64+
a mouse event includes different information than an input box editing event.
65+
66+
All [standard DOM event objects](https://developer.mozilla.org/en-US/docs/Web/API/Event)
67+
have a `target` property, a reference to the element that raised the event.
68+
In this case, `target` refers to the [`<input>` element](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement) and
69+
`event.target.value` returns the current contents of that element.
70+
71+
After each call, the `onKey()` method appends the contents of the input box value to the list
72+
in the component's `values` property, followed by a separator character (|).
73+
The [interpolation](guide/interpolation)
74+
displays the accumulating input box changes from the `values` property.
75+
76+
Suppose the user enters the letters "abc", and then backspaces to remove them one by one.
77+
Here's what the UI displays:
78+
79+
<code-example>
80+
a | ab | abc | ab | a | |
81+
</code-example>
82+
83+
84+
85+
<div class="lightbox">
86+
<img src='generated/images/guide/user-input/keyup1-anim.gif' alt="key up 1">
87+
</div>
88+
89+
90+
91+
<div class="alert is-helpful">
92+
93+
94+
95+
Alternatively, you could accumulate the individual keys themselves by substituting `event.key`
96+
for `event.target.value` in which case the same user input would produce:
97+
98+
<code-example>
99+
a | b | c | backspace | backspace | backspace |
100+
101+
</code-example>
102+
103+
104+
105+
</div>
106+
107+
108+
109+
{@a keyup1}
110+
111+
112+
### Type the _$event_
113+
114+
The example above casts the `$event` as an `any` type.
115+
That simplifies the code at a cost.
116+
There is no type information
117+
that could reveal properties of the event object and prevent silly mistakes.
118+
119+
The following example rewrites the method with types:
120+
121+
<code-example path="user-input/src/app/keyup.components.ts" region="key-up-component-1-class" header="src/app/keyup.components.ts (class v.1 - typed )"></code-example>
122+
123+
124+
125+
The `$event` is now a specific `KeyboardEvent`.
126+
Not all elements have a `value` property so it casts `target` to an input element.
127+
The `OnKey` method more clearly expresses what it expects from the template and how it interprets the event.
128+
129+
### Passing _$event_ is a dubious practice
130+
Typing the event object reveals a significant objection to passing the entire DOM event into the method:
131+
the component has too much awareness of the template details.
132+
It can't extract information without knowing more than it should about the HTML implementation.
133+
That breaks the separation of concerns between the template (_what the user sees_)
134+
and the component (_how the application processes user data_).
135+
136+
The next section shows how to use template reference variables to address this problem.
137+
138+
139+
140+
## Get user input from a template reference variable
141+
There's another way to get the user data: use Angular
142+
[**template reference variables**](guide/template-reference-variables).
143+
These variables provide direct access to an element from within the template.
144+
To declare a template reference variable, precede an identifier with a hash (or pound) character (#).
145+
146+
The following example uses a template reference variable
147+
to implement a keystroke loopback in a simple template.
148+
149+
<code-example path="user-input/src/app/loop-back.component.ts" region="loop-back-component" header="src/app/loop-back.component.ts"></code-example>
150+
151+
152+
153+
The template reference variable named `box`, declared on the `<input>` element,
154+
refers to the `<input>` element itself.
155+
The code uses the `box` variable to get the input element's `value` and display it
156+
with interpolation between `<p>` tags.
157+
158+
The template is completely self contained. It doesn't bind to the component,
159+
and the component does nothing.
160+
161+
Type something in the input box, and watch the display update with each keystroke.
162+
163+
164+
<div class="lightbox">
165+
<img src='generated/images/guide/user-input/keyup-loop-back-anim.gif' alt="loop back">
166+
</div>
167+
168+
169+
170+
<div class="alert is-helpful">
171+
172+
173+
174+
**This won't work at all unless you bind to an event**.
175+
176+
Angular updates the bindings (and therefore the screen)
177+
only if the app does something in response to asynchronous events, such as keystrokes.
178+
This example code binds the `keyup` event
179+
to the number 0, the shortest template statement possible.
180+
While the statement does nothing useful,
181+
it satisfies Angular's requirement so that Angular will update the screen.
182+
183+
</div>
184+
185+
186+
187+
It's easier to get to the input box with the template reference
188+
variable than to go through the `$event` object. Here's a rewrite of the previous
189+
`keyup` example that uses a template reference variable to get the user's input.
190+
191+
<code-example path="user-input/src/app/keyup.components.ts" region="key-up-component-2" header="src/app/keyup.components.ts (v2)"></code-example>
192+
193+
194+
195+
A nice aspect of this approach is that the component gets clean data values from the view.
196+
It no longer requires knowledge of the `$event` and its structure.
197+
{@a key-event}
198+
199+
200+
## Key event filtering (with `key.enter`)
201+
The `(keyup)` event handler hears *every keystroke*.
202+
Sometimes only the _Enter_ key matters, because it signals that the user has finished typing.
203+
One way to reduce the noise would be to examine every `$event.keyCode` and take action only when the key is _Enter_.
204+
205+
There's an easier way: bind to Angular's `keyup.enter` pseudo-event.
206+
Then Angular calls the event handler only when the user presses _Enter_.
207+
208+
<code-example path="user-input/src/app/keyup.components.ts" region="key-up-component-3" header="src/app/keyup.components.ts (v3)"></code-example>
209+
210+
211+
212+
Here's how it works.
213+
214+
<div class="lightbox">
215+
<img src='generated/images/guide/user-input/keyup3-anim.gif' alt="key up 3">
216+
</div>
217+
218+
219+
220+
221+
## On blur
222+
223+
In the previous example, the current state of the input box
224+
is lost if the user mouses away and clicks elsewhere on the page
225+
without first pressing _Enter_.
226+
The component's `value` property is updated only when the user presses _Enter_.
227+
228+
To fix this issue, listen to both the _Enter_ key and the _blur_ event.
229+
230+
231+
<code-example path="user-input/src/app/keyup.components.ts" region="key-up-component-4" header="src/app/keyup.components.ts (v4)"></code-example>
232+
233+
234+
235+
236+
## Put it all together
237+
The previous page showed how to [display data](guide/displaying-data).
238+
This page demonstrated event binding techniques.
239+
240+
Now, put it all together in a micro-app
241+
that can display a list of heroes and add new heroes to the list.
242+
The user can add a hero by typing the hero's name in the input box and
243+
clicking **Add**.
244+
245+
246+
<div class="lightbox">
247+
<img src='generated/images/guide/user-input/little-tour-anim.gif' alt="Little Tour of Heroes">
248+
</div>
249+
250+
251+
252+
Below is the "Little Tour of Heroes" component.
253+
254+
255+
<code-example path="user-input/src/app/little-tour.component.ts" region="little-tour" header="src/app/little-tour.component.ts"></code-example>
256+
257+
258+
259+
### Observations
260+
261+
* **Use template variables to refer to elements** &mdash;
262+
The `newHero` template variable refers to the `<input>` element.
263+
You can reference `newHero` from any sibling or child of the `<input>` element.
264+
265+
* **Pass values, not elements** &mdash;
266+
Instead of passing the `newHero` into the component's `addHero` method,
267+
get the input box value and pass *that* to `addHero`.
268+
269+
* **Keep template statements simple** &mdash;
270+
The `(blur)` event is bound to two JavaScript statements.
271+
The first statement calls `addHero`. The second statement, `newHero.value=''`,
272+
clears the input box after a new hero is added to the list.
273+
274+
275+
276+
## Source code
277+
278+
Following is all the code discussed in this page.
279+
280+
<code-tabs>
281+
282+
<code-pane header="click-me.component.ts" path="user-input/src/app/click-me.component.ts">
283+
284+
</code-pane>
285+
286+
<code-pane header="keyup.components.ts" path="user-input/src/app/keyup.components.ts">
287+
288+
</code-pane>
289+
290+
<code-pane header="loop-back.component.ts" path="user-input/src/app/loop-back.component.ts">
291+
292+
</code-pane>
293+
294+
<code-pane header="little-tour.component.ts" path="user-input/src/app/little-tour.component.ts">
295+
296+
</code-pane>
297+
298+
</code-tabs>
299+
300+
301+
Angular also supports passive event listeners. For example, you can use the following steps to make the scroll event passive.
302+
303+
1. Create a file `zone-flags.ts` under `src` directory.
304+
2. Add the following line into this file.
305+
306+
```
307+
(window as any)['__zone_symbol__PASSIVE_EVENTS'] = ['scroll'];
308+
```
309+
310+
3. In the `src/polyfills.ts` file, before importing zone.js, import the newly created `zone-flags`.
311+
312+
```
313+
import './zone-flags';
314+
import 'zone.js/dist/zone'; // Included with Angular CLI.
315+
```
316+
317+
After those steps, if you add event listeners for the `scroll` event, the listeners will be `passive`.
318+
319+
## Summary
320+
321+
You have mastered the basic primitives for responding to user input and gestures.
322+
323+
These techniques are useful for small-scale demonstrations, but they
324+
quickly become verbose and clumsy when handling large amounts of user input.
325+
Two-way data binding is a more elegant and compact way to move
326+
values between data entry fields and model properties.
327+
The next page, `Forms`, explains how to write
328+
two-way bindings with `NgModel`.

0 commit comments

Comments
 (0)