[Reactive Forms] FormArray에서 동적으로 추가 삭제할 수 있는 입력 양식 구현
14620 단어 AngularTypeScript
개요
평소에는 Angular를 사용했으며 반응형 양식의 동적 추가 삭제를 구현할 수있는 기회가있었습니다. 이미 많은 기사가 쓰여져 있습니다만, 심플하게 정리된 기사가 적었기 때문에 정리해 보려고 합니다.
본 기사에서는 이하의 2점에 대해서, 실장을 생각해 가고 싶습니다.
두 번째는 여기
[Reactive Forms] FormArray 구현을 자식 구성 요소로 잘라냅니다.
또한, FormGroup의 기본적인 설명에 대해서는 공식 문서에 양보합니다.
리액티브 폼(Angular 한국어 문서)
운영 환경
Angular CLI: 8.3.2
노드: 10.16.0
이번에 만드는 것
샘플 소스
ReactiveFormsModule 가져오기
먼저 준비를 위해 해당 모듈로 ReactiveFormsModule을 가져옵니다.
app.module.ts@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
구성 요소 구현
결론부터 쓰면 결국 다음과 같은 구현이 됩니다.
app.component.tsimport {Component, OnInit} from '@angular/core';
import {FormArray, FormBuilder, FormGroup} from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
form: FormGroup;
constructor(private fb: FormBuilder) {
}
ngOnInit() {
this.form = this.createForm();
}
createForm(): FormGroup {
return this.fb.group({
userName: [''],
userSkills: this.fb.array([])
});
}
get userSkillForm(): FormGroup {
return this.fb.group({
skillName: [''],
skillLevel: [''],
});
}
get userSkills(): FormArray {
return this.form.get('userSkills') as FormArray;
}
addUserSkill() {
this.userSkills.push(this.userSkillForm);
}
removeUserSkill(index: number) {
this.userSkills.removeAt(index);
}
}
프로시저는 먼저 기본 FormGroup에서 다음과 같이 FormArray를 정의합니다.
이번에는 초기 값으로 빈 배열을 정의합니다.
app.component.ts createForm(): FormGroup {
return this.fb.group({
userName: [''],
userSkills: this.fb.array([])
});
}
다음에 추가&삭제로 이용하는 메소드를 정의하고 있습니다.
머리 get
는 TypeScript getter 설정입니다.
FormArray는 FormGroup을 요소에 가지는 배열이므로,userSkillForm()
는 FormArray에 삽입할 FormGroup을 정의합니다.
userSkills()
는 FormArray의 배열을 그대로 돌려주고 있을 뿐이므로 엄밀하게는 필요 없습니다만, return의 내용을 봐도 아는 대로, 이것을 일일이 부르는 것은 중복이므로 간단하게 호출할 수 있도록 해 둡니다.
app.component.ts get userSkillForm(): FormGroup {
return this.fb.group({
skillName: [''],
skillLevel: [''],
});
}
get userSkills(): FormArray {
return this.form.get('userSkills') as FormArray;
}
마지막으로 폼을 추가 및 삭제하는 메서드를 정의합니다.addUserSkill()
userSkills의 끝에 FormGroup을 추가합니다.removeUserSkill(index: number)
에서는, 받은 index에 대응하는 요소를 삭제합니다.
app.component.ts addUserSkill() {
this.userSkills.push(this.userSkillForm);
}
removeUserSkill(index: number) {
this.userSkills.removeAt(index);
}
템플릿 구현
여기도 먼저 최종 구현부터
app.component.html<h3>フォーム</h3>
<form [formGroup]="form">
<div>名前: <input type="text" formControlName="userName"></div>
<div>
<p>スキル情報</p>
<div formArrayName="userSkills">
<div *ngFor="let skill of userSkills.controls; let i = index">
<div [formGroupName]="i">
<div>スキル名: <input type="text" formControlName="skillName"></div>
<div>レベル: <input type="number" formControlName="skillLevel"></div>
<button (click)="removeUserSkill(i)">削除</button>
</div>
</div>
</div>
<button (click)="addUserSkills()">スキルを追加</button>
</div>
</form>
<!-- Debug用の表示 -->
<h3>Debug</h3>
<ng-container *ngIf="form.value">
<pre>{{ form.value | json }}</pre>
</ng-container>
포인트로서는
샘플 소스
ReactiveFormsModule 가져오기
먼저 준비를 위해 해당 모듈로 ReactiveFormsModule을 가져옵니다.
app.module.ts@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
구성 요소 구현
결론부터 쓰면 결국 다음과 같은 구현이 됩니다.
app.component.tsimport {Component, OnInit} from '@angular/core';
import {FormArray, FormBuilder, FormGroup} from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
form: FormGroup;
constructor(private fb: FormBuilder) {
}
ngOnInit() {
this.form = this.createForm();
}
createForm(): FormGroup {
return this.fb.group({
userName: [''],
userSkills: this.fb.array([])
});
}
get userSkillForm(): FormGroup {
return this.fb.group({
skillName: [''],
skillLevel: [''],
});
}
get userSkills(): FormArray {
return this.form.get('userSkills') as FormArray;
}
addUserSkill() {
this.userSkills.push(this.userSkillForm);
}
removeUserSkill(index: number) {
this.userSkills.removeAt(index);
}
}
프로시저는 먼저 기본 FormGroup에서 다음과 같이 FormArray를 정의합니다.
이번에는 초기 값으로 빈 배열을 정의합니다.
app.component.ts createForm(): FormGroup {
return this.fb.group({
userName: [''],
userSkills: this.fb.array([])
});
}
다음에 추가&삭제로 이용하는 메소드를 정의하고 있습니다.
머리 get
는 TypeScript getter 설정입니다.
FormArray는 FormGroup을 요소에 가지는 배열이므로,userSkillForm()
는 FormArray에 삽입할 FormGroup을 정의합니다.
userSkills()
는 FormArray의 배열을 그대로 돌려주고 있을 뿐이므로 엄밀하게는 필요 없습니다만, return의 내용을 봐도 아는 대로, 이것을 일일이 부르는 것은 중복이므로 간단하게 호출할 수 있도록 해 둡니다.
app.component.ts get userSkillForm(): FormGroup {
return this.fb.group({
skillName: [''],
skillLevel: [''],
});
}
get userSkills(): FormArray {
return this.form.get('userSkills') as FormArray;
}
마지막으로 폼을 추가 및 삭제하는 메서드를 정의합니다.addUserSkill()
userSkills의 끝에 FormGroup을 추가합니다.removeUserSkill(index: number)
에서는, 받은 index에 대응하는 요소를 삭제합니다.
app.component.ts addUserSkill() {
this.userSkills.push(this.userSkillForm);
}
removeUserSkill(index: number) {
this.userSkills.removeAt(index);
}
템플릿 구현
여기도 먼저 최종 구현부터
app.component.html<h3>フォーム</h3>
<form [formGroup]="form">
<div>名前: <input type="text" formControlName="userName"></div>
<div>
<p>スキル情報</p>
<div formArrayName="userSkills">
<div *ngFor="let skill of userSkills.controls; let i = index">
<div [formGroupName]="i">
<div>スキル名: <input type="text" formControlName="skillName"></div>
<div>レベル: <input type="number" formControlName="skillLevel"></div>
<button (click)="removeUserSkill(i)">削除</button>
</div>
</div>
</div>
<button (click)="addUserSkills()">スキルを追加</button>
</div>
</form>
<!-- Debug用の表示 -->
<h3>Debug</h3>
<ng-container *ngIf="form.value">
<pre>{{ form.value | json }}</pre>
</ng-container>
포인트로서는
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
import {Component, OnInit} from '@angular/core';
import {FormArray, FormBuilder, FormGroup} from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
form: FormGroup;
constructor(private fb: FormBuilder) {
}
ngOnInit() {
this.form = this.createForm();
}
createForm(): FormGroup {
return this.fb.group({
userName: [''],
userSkills: this.fb.array([])
});
}
get userSkillForm(): FormGroup {
return this.fb.group({
skillName: [''],
skillLevel: [''],
});
}
get userSkills(): FormArray {
return this.form.get('userSkills') as FormArray;
}
addUserSkill() {
this.userSkills.push(this.userSkillForm);
}
removeUserSkill(index: number) {
this.userSkills.removeAt(index);
}
}
createForm(): FormGroup {
return this.fb.group({
userName: [''],
userSkills: this.fb.array([])
});
}
get userSkillForm(): FormGroup {
return this.fb.group({
skillName: [''],
skillLevel: [''],
});
}
get userSkills(): FormArray {
return this.form.get('userSkills') as FormArray;
}
addUserSkill() {
this.userSkills.push(this.userSkillForm);
}
removeUserSkill(index: number) {
this.userSkills.removeAt(index);
}
<h3>フォーム</h3>
<form [formGroup]="form">
<div>名前: <input type="text" formControlName="userName"></div>
<div>
<p>スキル情報</p>
<div formArrayName="userSkills">
<div *ngFor="let skill of userSkills.controls; let i = index">
<div [formGroupName]="i">
<div>スキル名: <input type="text" formControlName="skillName"></div>
<div>レベル: <input type="number" formControlName="skillLevel"></div>
<button (click)="removeUserSkill(i)">削除</button>
</div>
</div>
</div>
<button (click)="addUserSkills()">スキルを追加</button>
</div>
</form>
<!-- Debug用の表示 -->
<h3>Debug</h3>
<ng-container *ngIf="form.value">
<pre>{{ form.value | json }}</pre>
</ng-container>
formArrayName
에서 FormArray 지정 요약
이상, 우선은 하나의 컴퍼넌트 중에서 동적으로 추가, 삭제하는 폼을 구현해 보았습니다.
길어졌으므로, 아이 컴퍼넌트에 이것들을 잘라내는 구현은 다음에 쓰고 싶습니다.
[Reactive Forms] FormArray 구현을 자식 구성 요소로 잘라냅니다.
참고가되면 다행입니다!
참고문헌
Reference
이 문제에 관하여([Reactive Forms] FormArray에서 동적으로 추가 삭제할 수 있는 입력 양식 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/mashman/items/69cfe1a406dda8bbab80텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)