-
02 템플릿기반 폼(Template-driven Forms) 06앵귤러/04 폼(Forms) 2017. 9. 3. 13:30
ngSubmit으로 폼 제출
폼을 작성한 후에 폼을 제출할 수 있어야합니다. 폼 하단의 Submit 버튼은 아무것도 하지 않지만 유형 (type = "submit")으로 인해 폼 제출을 트리거합니다.
"폼 제출"은 현재 쓸모가 없습니다. 유용하게 사용하려면 폼의 ngSubmit 이벤트 프로퍼티를 영웅 폼 컴포넌트의 onSubmit()메서드에 바인딩합니다.
src/app/hero-form.component.html (ngSubmit)
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
당신은 이미 템플릿 참조변수인 #heroForm을 정의하고 값을 "ngForm"으로 초기화했습니다. 이제 이 변수를 사용하여 제출 버튼으로 폼에 액세스합니다.
heroForm 변수를 통해 폼의 전체 유효성을 이벤트바인딩을 사용하여 버튼의 disabled 프로퍼티에 바인딩합니다. 코드는 다음과 같습니다.
src/app/hero-form.component.html (submit-button)
<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
이제 응용프로그램을 실행하면 버튼이 활성화됩니다.
이제 이름을 삭제하면 "필수"규칙을 위반하게되고, 오류 메시지가 필연적으로 나타납니다. Submit버튼도 사용할 수 없습니다.
인상적이지 않았나요? 한번 생각해보십시오. Angular의 도움없이 버튼의 활성화/비활성화 상태를 폼의 유효성에 연결하려면 어떻게해야 합니까?
다음과 같이 간단합니다.
1. (향상된)폼 엘리먼트에 템플리트 참조 변수를 정의하십시오.
2. 여러 줄 떨어진 버튼에서 변수를 참조하십시오.
두 개의 폼 영역 토글 (추가 크레딧)
폼을 제출하는 것이 현재로서는 극적이지 않습니다.
더 눈에 띄는 시각효과를 위해 데이터 입력영역을 숨기고 다른 것을 표시하십시오.
<div>에 양식을 감싸고 hidden 프로퍼티를 HeroFormComponent.submitted 프로퍼티에 바인딩합니다.
src/app/hero-form.component.html (excerpt)
<div [hidden]="submitted">
<h1>Hero Form</h1>
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
<!-- ... all of the form ... -->
</form>
</div>
다음의 HeroFormComponent의 조각은 submitted 프로퍼티가 거짓이므로 메인 폼이 처음부터 폼을 제출할 때까지 표시됩니다.
src/app/hero-form.component.ts (submitted)
submitted = false;
onSubmit() { this.submitted = true; }
제출버튼을 클릭하면 submitted 플래그가 true가 되고 폼이 계획대로 사라집니다.
이제 앱은 제출 된 상태에있는 동안 다른 것을 보여줘야 합니다. 방금 작성한 <div> 래퍼 아래에 다음 HTML을 추가하십시오.
src/app/hero-form.component.html (excerpt)
<div [hidden]="!submitted">
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">Name</div>
<div class="col-xs-9 pull-left">{{ model.name }}</div>
</div>
<div class="row">
<div class="col-xs-3">Alter Ego</div>
<div class="col-xs-9 pull-left">{{ model.alterEgo }}</div>
</div>
<div class="row">
<div class="col-xs-3">Power</div>
<div class="col-xs-9 pull-left">{{ model.power }}</div>
</div>
<br>
<button class="btn btn-primary" (click)="submitted=false">Edit</button>
</div>
영웅이 보간 바인딩인 읽기 전용으로 표시됩니다. 이 <div>는 컴포넌트가 제출된 상태인 동안에만 나타납니다.
HTML에는 Edit버튼을 포함하며, 버튼의 클릭이벤트는 submitted 플래그를 지우는 표현식에 바인딩되어 있습니다.
Edit버튼을 클릭하면이 블록이 사라지고 편집 가능한 폼이 다시 나타납니다.
결론
이 페이지에서 설명한 Angular 폼은 데이터 수정, 유효성 검사 등에 대한 지원을 제공하기 위해 다음과 같은 프레임워크 기능을 가지고 있습니다.
l Angular HTML 폼 템플릿
l @Component 데코레이터가 있는 폼 컴포넌트 클래스.
l NgForm.ngSubmit 이벤트 프로퍼티에 바인딩하여 폼 제출 처리.
l #heroForm 및 #name과 같은 템플릿 참조변수.
l 양방향 데이터 바인딩을 위한 [(ngModel)] 구문
l 유효성 검사 및 폼 엘리먼트 변경 추적을 위해 name 어트리뷰트 사용.
l 컨트롤이 유효한지 확인하고 오류 메시지를 표시하거나 숨길 수있는 입력 컨트롤의 참조변수의 valid 프로퍼티
l NgForm 유효성에 바인딩하여 Submit 버튼의 사용가능상태 제어.
l 유효하지 않은 컨트롤에 대한 시각적 피드백을 사용자에게 제공하는 사용자 정의 CSS 클래스.
최종 프로젝트 폴더 구조는 다음과 같습니다
다음은 애플리케이션의 최종 버전 코드입니다.
src/app/hero-form.component.ts
import { Component } from '@angular/core';
import { Hero } from './hero';
@Component({
selector: 'hero-form',
templateUrl: './hero-form.component.html'
})
export class HeroFormComponent {
powers = ['Really Smart', 'Super Flexible',
'Super Hot', 'Weather Changer'];
model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet');
submitted = false;
onSubmit() { this.submitted = true; }
newHero() {
this.model = new Hero(42, '', '');
}
}
src/app/hero-form.component.html
<div class="container">
<div [hidden]="submitted">
<h1>Hero Form</h1>
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name"
#name="ngModel">
<div [hidden]="name.valid || name.pristine"
class="alert alert-danger">
Name is required
</div>
</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"
#power="ngModel">
<option *ngFor="let pow of powers" [value]="pow">{{pow}}</option>
</select>
<div [hidden]="power.valid || power.pristine" class="alert alert-danger">
Power is required
</div>
</div>
<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
<button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
</form>
</div>
<div [hidden]="!submitted">
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">Name</div>
<div class="col-xs-9 pull-left">{{ model.name }}</div>
</div>
<div class="row">
<div class="col-xs-3">Alter Ego</div>
<div class="col-xs-9 pull-left">{{ model.alterEgo }}</div>
</div>
<div class="row">
<div class="col-xs-3">Power</div>
<div class="col-xs-9 pull-left">{{ model.power }}</div>
</div>
<br>
<button class="btn btn-primary" (click)="submitted=false">Edit</button>
</div>
</div>
src/app/hero.ts
export class Hero {
constructor(
public id: number,
public name: string,
public power: string,
public alterEgo?: string
) { }
}
src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HeroFormComponent } from './hero-form.component';
@NgModule({
imports: [
BrowserModule,
FormsModule
],
declarations: [
AppComponent,
HeroFormComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
src/app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: '<hero-form></hero-form>'
})
export class AppComponent { }
src/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Forms</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet"
href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="forms.css"></head>
<body>
<my-app></my-app>
</body>
</html>
src/forms.css
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
'앵귤러 > 04 폼(Forms)' 카테고리의 다른 글
03 폼 유효성검사 02 (0) 2017.09.24 03 폼 유효성검사 01 (0) 2017.09.24 02 템플릿기반 폼(Template-driven Forms) 05 (0) 2017.09.03 02 템플릿기반 폼(Template-driven Forms) 04 (0) 2017.09.03 02 템플릿기반 폼(Template-driven Forms) 03 (0) 2017.09.03