Angular 2에서 양식 필드를 동적으로 추가하고 제거하는 방법
사용자가 추가 버튼을 클릭하는 동안 동적으로 입력 필드를 추가하려고합니다. 각 양식 필드에는 제거 버튼이 있어야합니다. 사용자가 양식 필드를 제거해야한다는 것을 클릭 할 때 Angular 2를 사용하여이를 수행해야합니다. 저는 Angular 2를 처음 사용합니다. 완성하도록 도와주세요.
내가 시도한 것
필드 세트 (선택 상자 3 개와 텍스트 상자 1 개)를 만들고 필드 추가라는 버튼을 만들었지 만 각도 1.x에서는 잘 작동했지만 각도 2에서는 완료하는 방법을 모르겠습니다. , 이것은 내 전체 작업의 링크 입니다.
app/app.component.ts
import {
Component
}
from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<div class="container">
<button class="btn btn-success bt-sm">add</button>
<form role="form" calss="form-inline">
<div class="form-group col-xs-3">
<label>Select State:</label>
<select class="form-control" [(ngModel)]="rules.State" id="sel1">
<option>State1</option>
<option>State2</option>
<option>State3</option>
<option>State4</option>
</select>
</div>
<div class="form-group col-xs-3">
<label>Rule:</label>
<input type="text" data-toggle="modal" data-target="#myModal" class="form- control">
</div>
<div class="form-group col-xs-3">
<label>Pass State :</label>
<select class="form-control" [(ngModel)]="rules.pass">
<option>State1</option>
<option>State2</option>
<option>State3</option>
<option>State4</option>
</select>
</div>
<div class="form-group col-xs-3">
<label>Fail State:</label>
<select class="form-control" [(ngModel)]="rules.fail">
<option>State1</option>
<option>State2</option>
<option>State3</option>
<option>State4</option>
</select>
</div>
</form>
</div>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">× </button>
<h4 class="modal-title">Rules Configuration</h4>
</div>
<div class="modal-body">
<p>Rules</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data- dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
`
})
export class AppComponent {
title = 'Rule Engine Demo';
rules: Rules = {
State: '',
pass: '',
fail: ''
};
이것은 몇 달 늦었지만 여기 튜토리얼을 기반으로 솔루션을 제공 할 것이라고 생각했습니다 . 요점은 양식에 접근하는 방식을 변경하면 관리하기가 훨씬 쉽다는 것입니다.
첫째, ReactiveFormsModule
일반 FormsModule
. 반응 형 양식을 사용하면 구성 요소 / 서비스에서 양식을 만든 다음 페이지에서 양식 자체를 생성하는 대신 페이지에 연결합니다. 약간 더 많은 코드이지만 훨씬 더 테스트 가능하고 훨씬 유연하며 사소하지 않은 많은 양식을 만드는 가장 좋은 방법을 말할 수 있습니다.
최종 결과는 개념적으로 다음과 같이 보일 것입니다.
양식 전체에 필요한 인스턴스 가있는 하나의 기반
FormGroup
이FormControl
있습니다. 예를 들어 내가 링크 한 튜토리얼에서와 같이 사용자가 이름을 한 번 입력 한 다음 원하는 수의 주소를 입력 할 수있는 양식을 원한다고 가정 해 보겠습니다. 모든 일회성 필드 입력은이 기본 양식 그룹에 있습니다.해당
FormGroup
인스턴스 내부 에는 하나 이상의FormArray
인스턴스가 있습니다. AFormArray
는 기본적으로 여러 컨트롤을 그룹화하고 반복하는 방법입니다. 또한FormGroup
배열 에 여러 인스턴스를 배치하고이를 더 큰 양식 내에 중첩 된 "미니 양식"으로 사용할 수도 있습니다.동적 내에 여러
FormGroup
및 / 또는FormControl
인스턴스 를 중첩FormArray
하면 유효성을 제어하고 여러 동적 부분으로 구성된 하나의 크고 반응적인 부분으로 양식을 관리 할 수 있습니다. 예를 들어, 사용자가 제출하도록 허용하기 전에 모든 단일 입력이 유효한지 확인하려는 경우 한 하위 양식의 유효성이 최상위 양식으로 "버블 링"되고 전체 양식이 무효화되어 쉽게 동적 입력을 관리합니다.A는 것처럼
FormArray
이며, 본질적으로 배열 인터페이스 주위하지만 형태로 조각의 래퍼, 당신은 밀어 수, 삽입 팝업 및 양식을 다시 복잡한 상호 작용을하지 않고 언제든지 컨트롤을 제거합니다.
링크 한 튜토리얼이 중단되는 경우 기본 아이디어를 설명하는 몇 가지 샘플 코드를 직접 구현할 수 있습니다 (내 예제에서는 TypeScript 사용).
기본 구성 요소 코드 :
import { Component, Input, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'my-form-component',
templateUrl: './my-form.component.html'
})
export class MyFormComponent implements OnInit {
@Input() inputArray: ArrayType[];
myForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
let newForm = this.fb.group({
appearsOnce: ['InitialValue', [Validators.required, Validators.maxLength(25)]],
formArray: this.fb.array([])
});
const arrayControl = <FormArray>newForm.controls['formArray'];
this.inputArray.forEach(item => {
let newGroup = this.fb.group({
itemPropertyOne: ['InitialValue', [Validators.required]],
itemPropertyTwo: ['InitialValue', [Validators.minLength(5), Validators.maxLength(20)]]
});
arrayControl.push(newGroup);
});
this.myForm = newForm;
}
addInput(): void {
const arrayControl = <FormArray>this.myForm.controls['formArray'];
let newGroup = this.fb.group({
/* Fill this in identically to the one in ngOnInit */
});
arrayControl.push(newGroup);
}
delInput(index: number): void {
const arrayControl = <FormArray>this.myForm.controls['formArray'];
arrayControl.removeAt(index);
}
onSubmit(): void {
console.log(this.myForm.value);
// Your form value is outputted as a JavaScript object.
// Parse it as JSON or take the values necessary to use as you like
}
}
Sub-Component Code: (one for each new input field, to keep things clean)
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'my-form-sub-component',
templateUrl: './my-form-sub-component.html'
})
export class MyFormSubComponent {
@Input() myForm: FormGroup; // This component is passed a FormGroup from the base component template
}
Base Component HTML
<form [formGroup]="myForm" (ngSubmit)="onSubmit()" novalidate>
<label>Appears Once:</label>
<input type="text" formControlName="appearsOnce" />
<div formArrayName="formArray">
<div *ngFor="let control of myForm.controls['formArray'].controls; let i = index">
<button type="button" (click)="delInput(i)">Delete</button>
<my-form-sub-component [myForm]="myForm.controls.formArray.controls[i]"></my-form-sub-component>
</div>
</div>
<button type="button" (click)="addInput()">Add</button>
<button type="submit" [disabled]="!myForm.valid">Save</button>
</form>
Sub-Component HTML
<div [formGroup]="form">
<label>Property One: </label>
<input type="text" formControlName="propertyOne"/>
<label >Property Two: </label>
<input type="number" formControlName="propertyTwo"/>
</div>
In the above code I basically have a component that represents the base of the form and then each sub-component manages its own FormGroup
instance within the FormArray
situated inside the base FormGroup
. The base template passes along the sub-group to the sub-component and then you can handle validation for the entire form dynamically.
Also, this makes it trivial to re-order component by strategically inserting and removing them from the form. It works with (seemingly) any number of inputs as they don't conflict with names (a big downside of template-driven forms as far as I'm aware) and you still retain pretty much automatic validation. The only "downside" of this approach is, besides writing a little more code, you do have to relearn how forms work. However, this will open up possibilities for much larger and more dynamic forms as you go on.
If you have any questions or want to point out some errors, go ahead. I just typed up the above code based on something I did myself this past week with the names changed and other misc. properties left out, but it should be straightforward. The only major difference between the above code and my own is that I moved all of the form-building to a separate service that's called from the component so it's a bit less messy.
addAccordian(type, data) { console.log(type, data);
let form = this.form;
if (!form.controls[type]) {
let ownerAccordian = new FormArray([]);
const group = new FormGroup({});
ownerAccordian.push(
this.applicationService.createControlWithGroup(data, group)
);
form.controls[type] = ownerAccordian;
} else {
const group = new FormGroup({});
(<FormArray>form.get(type)).push(
this.applicationService.createControlWithGroup(data, group)
);
}
console.log(this.form);
}
ReferenceURL : https://stackoverflow.com/questions/38007236/how-to-dynamically-add-and-remove-form-fields-in-angular-2
'UFO ET IT' 카테고리의 다른 글
명령 프롬프트에서 여러 클래스 경로 라이브러리가있는 jar 파일 실행 (0) | 2021.01.17 |
---|---|
avcapturesession으로 카메라 전환 (0) | 2021.01.17 |
Apache 사용자의 umask 설정 (0) | 2021.01.17 |
Rails에서 전체 애플리케이션이 공유하는 부분을 어디에 넣을까요? (0) | 2021.01.17 |
UIView에 대한 현재 각도 / 회전 / 라디안을 얻습니까? (0) | 2021.01.17 |