(번역)Angular - User Input

User input triggers DOM events. We listen to those events with event bindings that funnel updated values back into our components and models.


User input은 DOM 이벤트를 실행시킵니다. 우리는 그 이벤트들을 component들과 model들에게 업데이트된 값을 제공하는 이벤트 바인딩을 통해 듣습니다.


User actions such as clicking a link, pushing a button, and entering text raise DOM events. This page explains how to bind those events to component event handlers using the Angular event binding syntax.


링크나 버튼을 눌러 텍스트를 타고 들어가는 유저들의 액션은 DOM 이벤트를 일으킵니다. 이 페이지는 그러한 이벤트들을 어떻게 Angular syntax를 이용해 component이벤트 핸들러들로 묶을 수 있는지 설명합니다.



Binding to user input events

User input이벤트에 바인딩하기(묶기)


You can use Angular event bindings to respond to any DOM event. Many DOM events are triggered by user input. Binding to these events provides a way to get input from the user.


여러분은 Angular이벤트 바인딩을 어느 DOM이벤트에나 응답하도록 사용할 수 있습니다. 이런 DOM이벤트에 바인딩을 해두면 사용자들로부터 input을 받을 수 있게됩니다.


To bind to a DOM event, surround the DOM event name in parentheses and assign a quoted template statement to it.


DOM이벤트에 바인딩하기 위해서는 DOM이벤트 이름을 괄호로 묶고 인용된 template문을 적용하면 됩니다.


The following example shows an event binding that implements a click handler:


다음 예는 click 핸들러를 제공하는 이벤트바인딩의 예를 보여줍니다:


The (click) to the left of the equals sign identifies the button's click event as the target of the binding. The text in quotes to the right of the equals sign is the template statement, which responds to the click event by calling the component's onClickMe method.


등호표시 왼쪽의 ‘(click)’은 버튼의 클릭 이벤트를 바인딩타겟으로 할 것이라는걸 의미합니다. 등호 오른쪽에 있는 따옴표안의 텍스트는 template statement입니다. Template statement는 component의 onClickMe 메소드를 호출함으로서 click 이벤트에 응답합니다.


When writing a binding, be aware of a template statement's execution context. The identifiers in a template statement belong to a specific context object, usually the Angular component controlling the template. The example above shows a single line of HTML, but that HTML belongs to a larger component:


바인딩을 할때, template statement의 문맥을 주의하세요. Template statement에 있는 식별자는 특정 context object(주로 템플릿을 제어하는 Angular component)에 속합니다. 아래 예제는 한 줄의 HTML을 보여주지만 이 HTML은 더 큰 component에 속합니다:


srcappclick-me.component.ts

@Component({
selector: 'click-me',
  template: `
    <button (click)="onClickMe()">Click me!</button>
    {{clickMessage}}`
})
export class ClickMeComponent {
  clickMessage = '';

  onClickMe() {
    this.clickMessage = 'You are my hero!';
  }
}
When the user clicks the button, Angular calls the onClickMe method from ClickMeComponent. 사용자가 버튼을 누르면, Angular은 ClickMeComponent에서 ClickMe메소드를 호출합니다.

Get user input from the $event object

$event 객체로부터 사용자에게 입력값 받기


DOM events carry a payload of information that may be useful to the component. This section shows how to bind to the keyup event of an input box to get the user's input after each keystroke.


DOM이벤트들은 component에 유용할 지도 모르는 많은 정보를 가지고 다닌다. 이 섹션은 input박스의 keyup이벤트를 바인드해 사용자가 키보드를 두드릴때마다 입력값을 받을 수 있도록 한다.


The following code listens to the keyup event and passes the entire event payload ($event) to the component event handler.


다음 코드는 keyup이벤트를 들은 후 전체 이벤트 payload($event)를 component 이벤트핸들러로 보냅니다.


srcappkeyup.components.ts (template v.1)

template: `
  <input (keyup)="onKey($event)">
  <p>{{values}}</p>
`

When a user presses and releases a key, the keyup event occurs, and Angular provides a corresponding DOM event object in the $event variable which this code passes as a parameter to the component's onKey() method.


사용자가 키를 누르고 떼면, keyup이벤트가 발생하는데, Angular은 이에 대응하는 DOM이벤트 객체를 $event 변수에서 제공합니다. 여기 코드에서는 component의 onKey()메소드에 파라미터를 보냅니다.


srcappkeyup.components.ts (class v.1)

export class KeyUpComponent_v1 {
  values = '';

  onKey(event: any) { // without type info
    this.values += event.target.value + ' | ';
  }
}

The properties of an $event object vary depending on the type of DOM event. For example, a mouse event includes different information than a input box editing event.


$event 객체의 속성은 DOM이벤트의 다입에 따라 다양합니다. 예를 들어, 마우스 이벤트는 input박스를 수정하는 이벤트와는 다른 정보를 포함합니다.


All standard DOM event objects have a target property, a reference to the element that raised the event. In this case, target refers to the input element and event.target.value returns the current contents of that element.


모든 표준 DOM이벤트 객체는 타겟 속성을 가집니다. 타겟속성은 이벤트를 일으킨 element의 reference입니다. 이런 경우에, 타겟은 input요소를 의미하며 event.target.value는 그 요소의 현재 내용을 반환합니다.


After each call, the onKey() method appends the contents of the input box value to the list in the component's values property, followed by a separator character (|). The interpolation displays the accumulating input box changes from the values property.


매 호출마다, onKey()메소드는 input박스의 값을 component의 value속성에 구분자(|)를 넣어 붙입니다. 삽입문구는 값의 속성으로부터 축적된 input박스의 변화를 보여줍니다.


Suppose the user enters the letters "abc", and then backspaces to remove them one by one. Here's what the UI displays:

a | ab | abc | ab | a | |

사용자가 알파벳 “abc”를 입력했다가 하나씩 벡스페이스를 눌러 지웠다고 가정하자. UI는 다음과 같이 나타납니다:



Alternatively, you could accumulate the individual keys themselves by substituting event.key for event.target.value in which case the same user input would produce:

a | b | c | backspace | backspace | backspace |

다른 방법으로 여러분은 event.key를 event.target.value로 바꾸어서 각각의 키들을 축적할 수 있습니다. 이는 같은 결과를 보여줍니다:



Type the $event

$event 타이핑하기.


The example above casts the $event as an any type. That simplifies the code at a cost. There is no type information that could reveal properties of the event object and prevent silly mistakes.


위의 예제는 $event를 어느 타입으로든 던져줍니다. 이는 그에 따르는 대가가 있지만 코드를 간단하게 만들어 줍니다. 해당 이벤트 객체의 속성을 알 수 있는 타입정보가 없는 대신 멍청한 실수를 막을 수 있습니다.


The following example rewrites the method with types:


다음 예제는 메소드를 타입과 함께 다시 쓴것입니다:


srcappkeyup.components.ts (class v.1 - typed )

export class KeyUpComponent_v1 {
  values = '';


  onKey(event: KeyboardEvent) { // with type info
    this.values += (<HTMLInputElement>event.target).value + ' | ';
  }
}

The $event is now a specific KeyboardEvent. Not all elements have a value property so it casts target to an input element. The OnKey method more clearly expresses what it expects from the template and how it interprets the event.


$event는 이제 특정 KeyboardEvent입니다. 모든 요소들이 값속성을 가진것이 아니기 때문에 input요소에 타겟을 집어넣습니다. OnKey메소드는 템플릿으로부터 무엇을 기대하는지 그리고 어떻게 이벤트를 해석하는지 명료하게 표현합니다.


Passing $event is a dubious practice


$event를 전달하는것은 미심쩍은 표현입니다.


Typing the event object reveals a significant objection to passing the entire DOM event into the method: the component has too much awareness of the template details. It can't extract information without knowing more than it should about the HTML implementation. That breaks the separation of concerns between the template (what the user sees) and the component (how the application processes user data).


이벤트 객체를 적어 넣는것은 메소드에 전체 DOM이벤트를 전달하는것에 정말 반대한다는 뜻입니다: component는 템플릿의 세부사항에 대해 너무 많이 알고있습니다. 이는 HTML을 이식하는데 알아야 하는만큼보다 더 많이 알지 못하면 정보를 가져올 수 없습니다. 이는 템플릿(사용자들이 보는것)과 component(어떻게 어플리케이션이 사용자의 데이터를 이용하는지)의 분열 갈등을 부숩니다.


The next section shows how to use template reference variables to address this problem.


다음 섹션은 이러한 문제를 위해 어떻게 템플릿 참조변수를 사용할지 보여줍니다.



Get user input from a template reference variable

템플릿 참조변수로부터 사용자의 input받기.


There's another way to get the user data: use Angular template reference variables. These variables provide direct access to an element from within the template. To declare a template reference variable, precede an identifier with a hash (or pound) character (# ).


사용자의 데이터를 받을 수 있는 다른 방법이 있습니다: Angular 템플릿 참조변수를 사용하세요. 이 변수들은 템플릿 안에서 요소들에 직접적인 접근을 허용합니다. 템플릿의 참조변수를 선언하기 위해 해쉬(또는 우물정자) 글자#을 선행하세요.


The following example uses a template reference variable to implement a keystroke loopback in a simple template.


다음 예제는 간단한 템플릿으로 키보드 loopback을 시행하기 위해 템플릿 참조변수를 사용합니다.


srcapploop-back.component.ts

@Component({
  selector: 'loop-back',
  template: `
    <input #box (keyup)="0">
    <p>{{box.value}}</p>
  `
})
export class LoopbackComponent { }

The template reference variable named box, declared on the input element, refers to the input element itself. The code uses the box variable to get the input element's value and display it with interpolation between

tags.


box라고 불리는 템플릿 참조변수(input 요소에 선언되어있는)는 input요소 그자체를 나타냅니다. 또 코드는 box변수를 이용해 input요소의 값을 얻어오고

태그 사이에 그 값을 써넣습니다.


The template is completely self contained. It doesn't bind to the component, and the component does nothing.


이 템플릿은 철저히 자신을 내포하고 있다. component에 바인딩되어 있지도 않고 component는 아무것도 하지 않습니다.


Type something in the input box, and watch the display update with each keystroke.


input박스에 무언가 써넣어보고 키보드를 누를때마다 화면이 변경되는것을 보세요.


>This won't work at all unless you bind to an event.


이것은 여러분이 이벤트를 바인드 하지 않는 이상 작동하지 않을 것 입니다.


Angular updates the bindings (and therefore the screen) only if the app does something in response to asynchronous events, such as keystrokes. This example code binds the keyup event to the number 0, the shortest template statement possible. While the statement does nothing useful, it satisfies Angular's requirement so that Angular will update the screen.

It's easier to get to the input box with the template reference variable than to go through the $event object. Here's a rewrite of the previous keyup example that uses a template reference variable to get the user's input.


Angular는 바인딩을(따라서 스크린을) 앱이 비동기 이벤트들에 대한 응답으로 무언가를 할 때에만 업데이트합니다. 키보드를 두드리는 행위가 그러한 예입니다. 이 예제코드는 keyup이벤트를 가장 짧은 템플릿문인 숫자 0에 바인드 합니다. 템플릿문이 유용한 일을 하지는 않지만 Angular의 필요사항을 충족시켜 Angular가 화면을 업데이트 할것입니다. input박스에 접근하는것은 $event 객체를 통해 접근 하는 방법보다 템플릿 참조변수로 접근하는 것이 더 쉽습니다. 여기 이전의 템플릿 참조변수를 활용해 사용자의 input을 가져오는 keyup 예제를 다시 적었습니다.


srcappkeyup.components.ts (v2)

@Component({
  selector: 'key-up2',
  template: `
    <input #box (keyup)="onKey(box.value)">
    <p>{{values}}</p>
  `
})
export class KeyUpComponent_v2 {
  values = '';
  onKey(value: string) {
    this.values += value + ' | ';
  }
}

A nice aspect of this approach is that the component gets clean data values from the view. It no longer requires knowledge of the $event and its structure.


이러한 접근의 좋은점은 component가 뷰로부터 명확한 데이터를 가져온다는 것입니다. 또 $event와 구조에 대한 지식이 필요가 없습니다.



Key event filtering (with key.enter)


The (keyup) event handler hears every keystroke. Sometimes only the Enter key matters, because it signals that the user has finished typing. One way to reduce the noise would be to examine every $event.keyCode and take action only when the key is Enter.


keyup이벤트 핸들러는 모든 키보드 칠 때의 변화를 듣습니다. 때로 사용자가 타이핑을 마쳤다는 신호를 주는 엔터키가 문제입니다. 이러한 문제를 해결 하는 한가지 방법은 $event.keyCode마다 검사하고 키가 엔터일 때만 조취를 취하도록 하는 것입니다.


There's an easier way: bind to Angular's keyup.enter pseudo-event. Then Angular calls the event handler only when the user presses Enter.


더 쉬운 방법이 있습니다: Angular의 keyup.enter를 pseudo-event로 묶는것입니다. 그러면 Angular는 이벤트 핸들러를 사용자가 엔터를 누를 때만 부를 것 입니다.


srcappkeyup.components.ts (v3)

@Component({
  selector: 'key-up3',
  template: `
    <input #box (keyup.enter)="onEnter(box.value)">
    <p>{{value}}</p>
  `
})
export class KeyUpComponent_v3 {
  value = '';
  onEnter(value: string) { this.value = value; }
}

On blur

blur이벤트에서


In the previous example, the current state of the input box is lost if the user mouses away and clicks elsewhere on the page without first pressing Enter. The component's value property is updated only when the user presses Enter.


이전 예제에서, 사용자가 엔터를 우선치지 않고 마우스를 아무데나 누를때면 input박스의 현재 상태를 잃어버렸습니다. 그 component의 값속성은 사용자가 엔터를 칠 때만 업데이트되었습니다.


To fix this issue, listen to both the Enter key and the blur event.


이러한 이슈를 해결하기 위해, 엔터키와 blur이벤트를 모두 들어야 합니다.


srcappkeyup.components.ts (v4)

@Component({
  selector: 'key-up4',
  template: `
    <input #box
      (keyup.enter)="update(box.value)"
      (blur)="update(box.value)">

    <p>{{value}}</p>
  `
})
export class KeyUpComponent_v4 {
  value = '';
  update(value: string) { this.value = value; }
}

Put it all together 모두 합쳐봅시다. The previous page showed how to display data. This page demonstrated event binding techniques.


이전 페이지는 어떻게 데이터를 나타낼지에 관한 설명이었습니다. 이번 페이지는 증명된 이벤트 바인딩 테크닉에 관한 내용이었습니다.


Now, put it all together in a micro-app that can display a list of heroes and add new heroes to the list. The user can add a hero by typing the hero's name in the input box and clicking Add.


이제, 영웅 리스트를 보여주고 새로운 영웅을 추가 할 수 있는 마이크로-앱에 모두 넣어 봅시다. 사용자는 영웅의 이름을 input박스에 넣고 Add버튼을 눌러 영웅을 추가 할 수 있습니다.


Below is the "Little Tour of Heroes" component.


아래는 “작은 영웅의 여행” component입니다.


srcapplittle-tour.component.ts

@Component({
  selector: 'little-tour',
  template: `
    <input #newHero
      (keyup.enter)="addHero(newHero.value)"
      (blur)="addHero(newHero.value); newHero.value='' ">

    <button (click)="addHero(newHero.value)">Add</button>

    <ul><li *ngFor="let hero of heroes">{{hero}}</li></ul>
  `
})
export class LittleTourComponent {
  heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
  addHero(newHero: string) {
    if (newHero) {
      this.heroes.push(newHero);
    }
  }
}
Observations 관찰결과 Use template variables to refer to elements — The newHero template variable refers to the input element. You can reference newHero from any sibling or child of the input element. 


요소를 나태내기 위해 템플릿 변수를 사용하세요 — newHero 템플릿 변수는 input요소를 의미합니다. 여러분은 newHero변수를 input요소의 어떤 자매나 자식에게서 부터 참조할 수 있습니다.


Pass values, not elements — Instead of passing the newHero into the component's addHero method, get the input box value and pass that to addHero.


요소가 아니라, 값을 전달하세요. 


Keep template statements simple — The (blur) event is bound to two JavaScript statements. The first statement calls addHero. The second statement, newHero.value='', clears the input box after a new hero is added to the list.


템플릿변수를 간단하게 유지 하세요 — (blur)이벤트는 두 자바스크립트문을 가르킵니다. 처음 문장은 addHero를 부르고, 두번째 문장 newHero.value=‘’는 새로운 영웅이 리스트에 추가된 후 input상자를 지웁니다



Summary

요약 You have mastered the basic primitives for responding to user input and gestures.


여러분은 사용자의 입력과 제스쳐에 응답하는 기본적인 것들을 마스터했습니다.


These techniques are useful for small-scale demonstrations, but they quickly become verbose and clumsy when handling large amounts of user input. Two-way data binding is a more elegant and compact way to move values between data entry fields and model properties. The next page, Forms, explains how to write two-way bindings with NgModel.


이런 태크닉들은 작은단위의 증명에 유리합니다. 하지만 많은 양의 사용자 입력을 다룰 때면 이런것들은 장황해지고 어설퍼집니다. 두 방법으로 데이터를 바인딩 하는것은 데이터입력 필트와 모델 속성 사이에 값을 이동시키는 더 우아하고 최적화된 방법입니다. 다음페이지(Form)에서는 어떻게 NgModel을 가지고 두가지 바인딩을 쓸수 있는지 설명합니다.


+ Recent posts