본 포스트는 Angular - User Input 을 개인적인 학습목적으로 번역 및 정리한 것 입니다.
사용자 입력
링크나 버튼을 클릭하거나 텍스트를 입력하는 것과 같은 사용자가 웹페이지에서 하는 행동에 따라 DOM 이벤트가 발생합니다. 이렇게 발생한 DOM 이벤트를 Angular 에서는 이벤트 바인딩 구문을 사용하여 컴포넌트의 이벤트 핸들러와 DOM 이벤트를 연결(바인딩) 합니다.
사용자 입력을 이벤트에 바인딩
Angular 이벤트 바인딩 을 사용하면 DOM 이벤트에 응답(처리)할 수 있습니다. 많은 DOM 이벤트는 사용자 입력에 의해 트리거됩니다. 이러한 이벤트에 바인딩하여 사용자 입력을 받을 수 있습니다.
DOM 이벤트와 사용자 입력을 연결하려면 DOM 이벤트 이름을 괄호로 묶고 따옴표 안에 템플릿문 을 지정합니다.
다음 예제는 클릭 핸들러를 지정하는 이벤트 바인딩을 보여줍니다.
▼ src / app / click-me.component.html
<button (click)="onClickMe()">Click me!</button>
등호(=
) 왼쪽에 (click)
은 바인딩 대상 으로 DOM 이벤트 중, 마우스 버튼을 클릭할 시 발생하는 이벤트를 의미합니다. 등호 오른쪽 따옴표로 둘러싸인 onClickMe()
는 click
이벤트가 발생할 경우 onClickMe
메소드를 호출하여 해당 이벤트에 응답하는 템플릿문 입니다.
바인딩을 작성할 때는 템플릿 문장의 실행 컨텍스트 에 주의해야 합니다. 템플릿문의 식별자는 특정 컨텍스트 객체에 속합니다. 일반적으로 템플릿을 제어하는 Angular 컴포넌트입니다.
▼ src / app / click-me.component.ts
@Component({
selector: 'app-click-me',
template: `
<button (click)="onClickMe()">Click me!</button>
{{clickMessage}}`
})
export class ClickMeComponent {
clickMessage = '';
onClickMe() {
this.clickMessage = 'You are my hero!';
}
}
사용자가 버튼을 클릭하면 Angular는 ClickMe
컴포넌트의 onClickMe
메서드를 호출합니다.
$ event 객체에서 사용자 입력 받기
DOM 이벤트에는 컴퍼넌트에서 유용하게 사용할 수 있는 정보 페이로드가 있습니다. 이번 섹션에서는 입력 상자와 keyup
이벤트를 바인딩하고 각 키 입력에 대한 사용자의 입력을 취득하는 방법을 살펴보도록 하겠습니다.
다음 코드는 keyup
이벤트를 수신하고 이벤트 페이로드($event
) 전체를 컴포넌트의 이벤트 핸들러(onKey
)에 전달합니다.
▼ src / app / keyup.components.ts (template v.1)
template: `
<input (keyup)="onKey($event)">
<p>{{values}}</p>
`
사용자가 키를 눌렀다 떼면 keyup
이벤트가 발생하고, Angular는 $event
변수에 해당 DOM 이벤트 객체를 제공합니다. 이 코드에서는 $event
변수를 컴포넌트의 onKey()
메서드의 입력 파라메터로 전달합니다.
▼ src / app / keyup.components.ts (class v.1)
export class KeyUpComponent_v1 {
values = '';
onKey(event: any) { // without type info
this.values += event.target.value + ' | ';
}
}
$event
객체의 속성은 DOM 이벤트의 유형에 따라 달라집니다. 예를 들어, 마우스 이벤트는 입력 상자 편집 이벤트와 다른 정보가 포함되어 있습니다.
모든 표준 DOM 이벤트 객체에는 이벤트를 발생시킨 요소에 대한 참조인 target
속성이 있습니다. 이번 경우 target
은 <input>
요소 를 참조하고 event.target.value
은 그 요소의 현재 내용을 반환해 줍니다.
각 호출 후 onKey()
메서드는 입력 상자값의 내용을 컴포넌트의 values
속성 목록에 추가한 다음에 구분자(|
)를 추가합니다. 보간은 values
속성에서 누적된 입력 상자의 변경을 표시합니다.
사용자가 문자 "abc"를 입력 한 후 백 스페이스 하나씩 삭제한다고 하면, UI에 표시되는 내용은 다음과 같습니다.
또는 event.key
를 event.target.value
대신에 대입함으로써 개별키 자체를 누적할 수도 있습니다. 이 경우 같은 사용자 입력에 대해서 화면에 출력되는 내용은 다음과 같습니다.
a | b | c | backspace | backspace | backspace |
$ event 형식
위 예제에서 우리는 $event
를 any
형식으로 캐스팅 했습니다. 이것으로 코드를 단순화하였지만, 이벤트 객체의 속성에는 실수를 방지 할 수 있는 형식 정보가 없습니다.
아래 예제는 형식(type)을 추가하여 다시 작성한 것입니다.
▼ src / app / keyup.components.ts (class v.1 - typed)
export class KeyUpComponent_v1 {
values = '';
onKey(event: KeyboardEvent) { // with type info
this.values += (<HTMLInputElement>event.target).value + ' | ';
}
}`
$event
가 구체적으로 KeyboardEvent
로 한정되었습니다. 모든 요소가 value
속성을 가지고있는 것이 아니기 때문에, input 요소에 target
캐스팅합니다. onKey
방법은 템플릿에서 기대하는 것과 이벤트를 어떻게 해석 하는지를 좀 더 명확하게 표현합니다.
$ event 를 전달하는 것은 모호합니다.
이벤트 객체 유형을 지정할 수 있는 DOM 이벤트 전체를 메소드에 건네 주는 것은 심각한 반대에 부딪칩니다. 컴포넌트가 템플릿에 대해서 너무 상세히 알아야 합니다. 컴포넌트가 HTML 에 대해서 알아야 하는 것보다 더 많은 정보를 알아야 정보를 추출할 수 있습니다.
이로 인해 템플릿 (사용자가 볼 것)과 컴포넌트 (앱이 사용자 데이터를 어떻게 처리할지) 간의 관심의 분리가 깨집니다.
다음 섹션에서는 템플릿 참조 변수를 사용하여 이 문제를 해결하는 방법을 살펴보도록 하겠습ㄴ다.
템플릿 참조 변수에서 사용자 입력 받기
사용자 데이터를 얻는 또 다른 방법은 Angular의 템플릿 참조 변수를 사용하는 것입니다. 이러한 변수는 템플릿 내에서 요소(element)에 대한 직접 액세스를 제공합니다. 템플릿 참조 변수를 선언하려면 식별자 앞에 해시 (또는 파운드) 문자 (#
)를 넣습니다.
다음 예제에서는 템플릿 참조 변수를 사용하여 간단한 템플릿에 키 스트로크 루프백을 구현하고 있습니다.
▼ src / app / loop-back.component.ts
@Component({
selector: 'app-loop-back',
template: `
<input #box (keyup)="0">
<p>{{box.value}}</p>
`
})
export class LoopbackComponent { }
<input>
요소에서 선언된 box
라는 템플릿 참조변수는 <input>
요소자체를 참조합니다. 이 코드는 box
변수를 사용하여 <input>
요소의 value
를 <p>
태그 사이에 보간({{
, }}
)을 사용하여 표시합니다.
템플릿은 완전히 자체적으로 동작합니다. 컴포넌트에 바인딩되지 않았기 때문에 컴포넌트는 아무것도하지 않습니다.
입력 상자에 뭔가를 입력하고 각 키에 대한 디스플레이의 갱신을 살펴보시기 바랍니다.
이벤트를 바인딩하지 않은 경우, 이 코드는 전혀 동작하지 않습니다
Angular는 응용 프로그램이 키 입력 등의 비동기 이벤트에 대한 응답으로 뭔가를 할 경우에만 바인딩 (즉 화면)을 업데이트합니다. 이 예제 코드는 가장 짧은 템플릿문인 숫자 0 에keyup
이벤트를 바인딩합니다. 이 구문은 아무런 도움이되지 않지만, Angular의 요구를 만족시키고 Angular 가 화면을 갱신하도록합니다.
$event
객체를 통하는 것보다 템플리트 참조 변수를 사용하여 입력상자에 접근하는 것이 더 쉽습니다. 다음은 사용자 입력을 받는 이전 keyup
예제를 템플릿 참조 변수를 사용하여 다시 작성한 것입니다.
▼ src / app / keyup.components.ts (v2)
@Component({
selector: 'app-key-up2',
template: `
<input #box (keyup)="onKey(box.value)">
<p>{{values}}</p>
`
})
export class KeyUpComponent_v2 {
values = '';
onKey(value: string) {
this.values += value + ' | ';
}
}
이 방법의 장점은 컴포넌트가 뷰에서 깨끗한 데이터 값을 얻을 수 있다는 것입니다. $event
객체와 그 구조에 대한 지식이 더 이상 필요하지 않습니다.
키 이벤트 필터링 ( key.enter
사용)
(keyup)
이벤트 핸들러는 모든 키 입력을 포착합니다. 때때로 사용자가 입력을 완료한 것을 알기 위해 Enter 키 만 필요한 경우가 있습니다. 이를 위한 하나의 방법은 매회 $event.keyCode
을 확인하고 키가 Enter 경우에만 조치를 취하는 것입니다.
더 쉬운 방법은 Angular의 keyup.enter
라는 유사 이벤트에 바인딩하는 것입니다. Angular는 사용자가 Enter 키를 눌렀을 때만 이벤트 핸들러를 호출합니다.
▼ src / app / keyup.components.ts (v3)
@Component({
selector: 'app-key-up3',
template: `
<input #box (keyup.enter)="onEnter(box.value)">
<p>{{value}}</p>
`
})
export class KeyUpComponent_v3 {
value = '';
onEnter(value: string) { this.value = value; }
}
위 코드는 다음과 같이 동작합니다.
blur 이벤트
앞의 예에서 입력 상자의 현재 상태는 사용자가 Enter 키를 한 번 누르지 않고 마우스를 이동하여 페이지의 다른 위치를 클릭하면 사라집니다. 컴포넌트의 value
속성은 사용자가 Enter 키를 누를 때만 업데이트됩니다.
이 문제를 해결하려면 Enter 키와 blur 이벤트를 모두 수신합니다.
▼ src / app / keyup.components.ts (v4)
@Component({
selector: 'app-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; }
}
모두 합치기
이전에 데이터를 표시하는 방법을 보여주었습니다. 이 페이지에서 이벤트 바인딩 기술에 대해 설명했습니다.
그러면 모든 영웅 목록을 표시하고 새로운 영웅을 목록에 추가 할 수있는 마이크로 응용 프로그램에 정리합시다. 사용자가 입력 상자에 영웅의 이름을 입력하고 Add 를 클릭하면 영웅을 추가 할 수 있습니다.
다음은 “Little Tour of Heroes” 의 컴포넌트입니다.
▼ src / app / little-tour.component.ts
@Component({
selector: 'app-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);
}
}
}
주목할 점
-
템플릿 변수를 사용하여 요소를 참조하는 -
newHero
템플릿 변수는<input>
요소를 참조합니다.<input>
요소의 어떤 형제나 자식에서도newHero
를 참조할 수 있습니다. -
요소가 아닌값을 전달 - 컴포넌트의
addHero
메소드에newHero
를 전달하는 대신 입력상자의 값을 취득하여addHero
에 전달합니다. -
템플릿 문을 간단하게 -
(blur)
이벤트는 두 JavaScript 문에 바인딩되어 있습니다. 첫 번째 문장은addHero
을 호출합니다. 두 번째newHero.value=''
는 새로운 영웅이 목록에 추가된 후 입력상자를 클리어합니다.
정리
사용자 입력과 제스처에 응답하기위한 기본적인 기능을 마스터했습니다.
이러한 방법은 소규모 예시에서는 유용하게 사용할 수 있지만, 대량의 사용자 입력을 처리하는 경우에는 즉시 복잡해집니다. 양방향 데이터 바인딩은 데이터 입력 필드와 모델 속성 사이에서 값을 공유하기 위한 더 우아하고 간단한 방법입니다. 다음 페이지 Forms에서는 NgModel를 사용하여 양방향 바인딩을 만드는 방법에 대해 설명합니다.
'모듈, 프레임웍 > Angular' 카테고리의 다른 글
Angular - Routing 과 Guard 사용 (0) | 2019.02.12 |
---|---|
Angular 외부 라이브러리 사용하기 (0) | 2018.09.27 |
Font Awesome @ Angular (0) | 2018.09.22 |
Flex Layout 사용하기 (0) | 2018.09.16 |
음악신청 게시판 만들기 (0) | 2018.09.15 |