-
02 템플릿기반 폼(Template-driven Forms) 04앵귤러/04 폼(Forms) 2017. 9. 3. 13:20
ngModel을 사용한 양방향 데이터 바인딩
지금 바로 앱을 실행하면 조금 실망할 것입니다.
Hero를 바인딩하지 않았기 때문에 영웅 데이터가 표시되지 않습니다. 이전 페이지에서 표시하는 법을 배웠습니다. 데이터표시 섹션에서 프로퍼티 바인딩을 배웠습니다. 사용자입력 섹션에서 이벤트바인딩을 사용하여 DOM 이벤트를 수신하는 방법과 표시된 값으로 컴포넌트 프로퍼티를 업데이트하는 방법을 배웠습니다.
이제는 동시에 표시하고 듣고 추출해야합니다.
이미 알고있는 기술을 사용할 수 있지만 새구문[(ngModel)]을 사용하면 폼을 모델에 쉽게 바인딩 할 수 있습니다.
Name의 <input> 태그를 찾아 다음과 같이 수정하십시오.
src/app/hero-form.component.html (excerpt)
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name">
TODO: remove this: {{model.name}}
입력태그 뒤에 진단보간을 추가하여 수행중인 작업을 볼 수 있습니다. 완료되면 삭제할 수 있도록 메모를 남겨 두었습니다.
바인딩 구문 보세요: [(ngModel)] = "...".
데이터를 표시하려면 하나 더 추가해야 합니다. 폼에 대한 템플릿 변수를 선언하십시오. 다음과 같이 <form> 태그를 #heroForm = "ngForm"으로 수정하십시오.
src/app/hero-form.component.html (excerpt)
<form #heroForm="ngForm">
변수 heroForm은 이제 폼 전체를 관리하는 NgForm 디렉티브에 대한 참조변수입니다.
NgForm 디렉티브
NgForm 디렉티브는 무엇입니까? 당신은 NgForm디렉티브를 추가하지 않았습니다.
Angular가 추가했습니다. Angular가 자동으로 NgForm 디렉티브를 만들고 <form> 태그에 첨부합니다.
NgForm 디렉티브는 추가 기능을 사용하여 form엘리먼트를 보완합니다. ngModele디렉티브와 name 어트리뷰트를 사용하여 엘리먼트에 적용한 컨트롤을 보유하고 유효성을 포함하여 프로퍼티를 모니터링합니다. 또한 모든 유효한 컨트롤이 유효한 경우에만 true인 고유한 valid프로퍼티를 가집니다.
이제 앱을 실행하고 Name 입력박스에 입력을 시작하고 문자를 추가 및 삭제하면 보간된 텍스트에서 문자가 나타나고 사라지는 것을 볼 수 있습니다. 어떤 시점에서 다음과 같이 보일 수 있습니다.
진단해보면 입력값이 실제로 입력박스에서 모델로 그리고 다시 되돌아 간다는 것을 알 수 있습니다.
<input>태그가 영웅의 이름라는 것을 알 수 있도록 name 어트리뷰트를 추가하고 "name"으로 설정하였습니다. 어트리뷰트에 고유한 값을 사용하지면, 설명이 포함된 이름을 사용하면 도움이됩니다. [(ngModel)]을 폼과 함께 사용하는 경우 name 어트리뷰트를 정의하는 것은 필수입니다.
내부적으로 Angular는 FormControl 인스턴스를 생성하고 <form> 태그에 Angular가 첨부했던 NgForm 디렉티브를 등록합니다. 각 FormControl은 name 어트리뷰트에 지정한 이름으로 등록됩니다. 이전 섹션인 The NgForm디렉티브에서 더 많은 것을 알 수 있습니다.
유사하게 [(ngModel)] 바인딩 및 name 속성을 Alter Ego 및 Hero Power에 추가합니다. 입력박스 바인딩 메시지를 버리고 컴포넌트의 diagnostic 프로퍼티에 새 바인딩을 추가합니다. 그런 다음 양방향 데이터바인딩이 전체 영웅 모델에서 작동하는 것을 확인할 수 있습니다.
수정 후, 폼의 핵심은 다음과 같습니다.
src/app/hero-form.component.html (excerpt)
{{diagnostic}}
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name">
</div>
<div class="form-group">
<label for="alterEgo">Alter Ego</label>
<input type="text" class="form-control" id="alterEgo"
[(ngModel)]="model.alterEgo" name="alterEgo">
</div>
<div class="form-group">
<label for="power">Hero Power</label>
<select class="form-control" id="power"
required
[(ngModel)]="model.power" name="power">
<option *ngFor="let pow of powers" [value]="pow">{{pow}}</option>
</select>
</div>
l 각 입력 엘리먼트는 id 어트리뷰트를 가지며, 이 id는 label엘리먼트의 for 어트립뷰트와 입력 컨트롤에 대한 레이블을 일치시키는데 사용합니다.
l 각 입력 엘리먼트는 name어트리뷰트를 가지며, 이 name은 Angular 폼이 폼에 컨트롤을 등록하기 위해 사용합니다.
이제 앱을 실행하고 모든 영웅 모델의 프로퍼티를 변경하면 폼은 다음과 같이 표시될 것입니다.
폼 상단쪽의 진단을 보면 모든 변경 사항이 모델에 반영되었음을 확인할 수 있습니다.
상단에 있는 {{diagnostic}}바인딩을 삭제합니다.
ngModel을 사용하여 컨트롤상태 및 유효성 추적
폼에서 ngModel을 사용하면 단순한 양방향 데이터바인딩 이상의 것을 사용할 수 있습니다. 또한 사용자가 컨트롤을 터치했는지, 값이 변경되었는지 또는 값이 유효하지 않은지 여부를 알려줍니다.
NgModel디렉티브는 상태추적만 하지 않습니다. 상태를 반영하는 특별한 Angular CSS 클래스로 컨트롤을 업데이트합니다. 이러한 클래스 이름을 사용하여 컨트롤의 모양을 변경할 수 있습니다.
상태
true일 때 Class
false일 때 Class
컨트롤을 방문
ng-touched
ng-untouched
컨트롤값 변경
ng-dirty
ng-pristine
컨트롤값 유효함
ng-valid
ng-invalid
name <input> 태그에 일시적으로 spy라는 템플릿 참조변수를 추가하고 이를 입력 CSS클래스를 표시하는 데 사용합니다.
src/app/hero-form.component.html (excerpt)
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name"
#spy>
<br>TODO: remove this: {{spy.className}}
이제 앱을 실행하고 Name 입력박스를 살펴보십시오. 다음 단계를 정확하게 따르십시오.
1. 보고기만 하고 만지지 마세요.
2. 이름 박스 안쪽을 클릭 한 다음 바깥 쪽을 클릭하십시오.
3. 이름 끝에 슬래시를 추가하십시오.
4. 이름을 지우십시오.
동작과 효과는 다음과 같습니다.
다음과 같은 전환 및 클래스 이름이 표시되어야 합니다.
ng-valid/ng-invalid 쌍이 가장 흥미롭습니다. 이유는 값이 유효하지 않을 때 강력한 시각적 신호를 보내야 하기 때문입니다. 또한 필수 필드를 표시할 필요가 있습니다. 시각적 피드백을 만들려면 ng- * CSS 클래스에 대한 정의를 추가하십시오.
#spy 템플릿 참조변수와 TODO를 삭제합니다.
'앵귤러 > 04 폼(Forms)' 카테고리의 다른 글
02 템플릿기반 폼(Template-driven Forms) 06 (0) 2017.09.03 02 템플릿기반 폼(Template-driven Forms) 05 (0) 2017.09.03 02 템플릿기반 폼(Template-driven Forms) 03 (0) 2017.09.03 02 템플릿기반 폼(Template-driven Forms) 02 (0) 2017.09.03 02 템플릿 기반 폼(Template-driven Forms) 01 (0) 2017.09.03