즉석에서 동적 Angular 양식 빌드
14638 단어 angularwebdevtutorialjavascript
FormControls
가 있는 구성 요소에서도 각각을 "적절하게"디자인하고 모든 것이 서로 잘 맞는지 확인해야 합니다.또한 빠르게 변화하는 비즈니스 및 규정 요구 사항을 충족하기 위해 자주 변경될 수 있음을 염두에 두어야 합니다.
비즈니스 개체 모델을 설명하는 메타데이터를 사용하여 즉석 양식을 만드는 방법을 살펴보겠습니다.
메타데이터
메타데이터는 시스템에 다음 내용을 표시합니다.
JSON으로 구조화되지만 원하는 언어(JSON+LD, csv, XML 또는 원하는 형식)를 분명히 사용할 수 있습니다.
데이터 소스는 API, 파일 또는 기타 사용 가능한 데이터 소스일 수도 있습니다.
JSON에서는 다음과 같이 표시됩니다(필요에 맞게 조정할 수 있음).
// question-base.ts
export class QuestionBase<T> {
value: T;
key: string;
label: string;
required: boolean;
order: number;
controlType: string;
placeholder: string;
iterable: boolean;
...
}
이것은 다음과 같이 생성할 다른 모든 종류의 요소에 대한 골격이 됩니다.
이러한 각 양식 요소는 동일한 항목
Class
을 공유하고 적절한 필요에 맞게 확장합니다. 예를 들어 option
는 <select>
요소에만 유용합니다.// question-dropdown.ts
import { QuestionBase } from './question-base';
export class DropdownQuestion extends QuestionBase<string> {
controlType = 'dropdown';
options: { key: string, value: string }[] = [];
constructor(options: {} = {}) {
super(options);
this.options = options['options'] || [];
}
}
구성 요소
코드를 유연하고 안정적이며 쉽게 테스트하고 유지 관리할 수 있도록 하기 위해 두 부분으로 나뉩니다. 첫째, 항상 앱의 구성 요소에서 래퍼로 호출되는 구성 요소( app-dynamic-form
)가 있습니다.
<!-- app.component.html -->
<app-dynamic-form #dynamicForm
[questions]="questions"></app-dynamic-form>
그런 다음 각각의 별도 양식 필드를 만들기 위해 app-question
에 의해 호출되고 반복되는 app-dynamic-form
구성 요소:
<!-- dynamic-form.component.html -->
...
<div *ngFor="let question of questions"
class="form-row">
<app-question [question]="question"
[form]="form"></app-question>
</div>
...
iterable(반복 가능)하게 만들기
위에서 볼 수 있듯이 app-question
는 ngFor
의 컬렉션을 순환하는 questions
안에 래핑되어 있습니다.
이 구성 요소 안에는 QuestionBase
가 있습니다. 그것의 임무는 객체에 주어진 필드 유형에 따라 올바른 HTMLElement를 표시하는 것입니다.
<!-- dynamic-form-question.component.html -->
<div [ngSwitch]="question.controlType">
<input *ngSwitchCase="'textbox'"
[formControl]="questionControl(index)"
[placeholder]="question.placeholder"
[attr.min]="question['min']"
[attr.max]="question['max']"
[attr.pattern]="question['pattern']"
[id]="questionId(index)"
[type]="question['type']">
<select [id]="question.key"
*ngSwitchCase="'dropdown'"
[formControl]="questionControl(index)">
<option value=""
disabled
*ngIf="!!question.placeholder"
selected>{{ question.placeholder }}</option>
<option *ngFor="let opt of question['options']"
[value]="opt.key">{{ opt.value }}</option>
</select>
...
</div>
ngSwitch
에 할당된 [attr.min]="question['min']"
속성이 있는 요소에 options
와 같은 속성 값을 전달하는 방식을 눈치챘을 것입니다.
// question-dropdown.ts
import { QuestionBase } from './question-base';
export class TextboxQuestion extends QuestionBase<string> {
type: string;
min: number | string;
...
constructor(options: {} = {}) {
super(options);
this.type = options['type'] || 'text';
this.min = options['min'];
...
}
하지만 constructor
표시할 뿐만 아니라 FormControl
도 좋습니다! 이제 몇 가지 콘텐츠 프로젝션을 살펴보겠습니다.
<!-- dynamic-form-question.component.html -->
<div *ngIf="question.iterable; else formTmpl">
<div *ngFor="let field of questionArray.controls;
let i=index; first as isFirst last as isLast">
<ng-container [ngTemplateOutlet]="formTmpl"
[ngTemplateOutletContext]="{index: i}"></ng-container>
<button *ngIf="question.iterable && questionArray.controls.length > 1"
(click)="removeQuestion(i)"
type="button">-</button>
<button *ngIf="question.iterable && isLast"
(click)="addQuestion()"
type="button">+</button>
</div>
</div>
이 라인 FormArray
은 <div *ngIf="question.iterable; else formTmpl">
의 컬렉션 또는 간단한 FormArray
를 표시하기로 결정하여 FormControl
로 래핑된 라인임을 알 수 있습니다. 이것이 우리가 어떤 반복 단계에 있는지 알 수 있는 유일한 방법이라는 점을 감안하여 현재 인덱스를 ng-template
로 전달하고 있습니다.
<!-- dynamic-form-question.component.html -->
..
<ng-template #formTmpl
let-index="index">
<label [attr.for]="questionId(index)">{{ questionLabel(index) }}</label>
<div [ngSwitch]="question.controlType">
...
여기서 문제는 올바른 let-index="index"
요소(우리가 반복하고 있는 요소)와의 "링크"를 유지하는 것입니다. 왜냐하면 이 구성을 사용하면 question
에 questions
가 있기 때문입니다. a question
가 반복 가능한지 확인하는 유일한 방법은 question
의 iterable
속성을 확인하는 것이기 때문에 유형과 클래스는 이 시점에서 동일하게 유지됩니다.
question
로 주입된 index
속성 덕분에 다음을 사용하여 <ng-template #formTmpl let-index="index">
에서 쉽게 검색할 수 있습니다.
<ng-container [ngTemplateOutlet]="formTmpl"
[ngTemplateOutletContext]="{index: i}"></ng-container>
컬렉션의 올바른 반복 작업을 수행합니다.
데모 및 코드
모든 소스 코드는 Github에서 사용할 수 있으며 동적 양식의 놀라운 기능을 보고 싶다면 이미 데모를 사용할 수 있습니다!
최대화
/
각도 동적 형태
Angular를 사용하여 데이터에서 즉각적인 양식 생성
🔥 Demo available here 🔥
학점
사진 제공: Patrick Langwallner on Unsplash
다시 읽고 수정해 주셔서 감사합니다.
Reference
이 문제에 관하여(즉석에서 동적 Angular 양식 빌드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/max/build-dynamic-angular-forms-on-the-fly-4n3m
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
<!-- app.component.html -->
<app-dynamic-form #dynamicForm
[questions]="questions"></app-dynamic-form>
<!-- dynamic-form.component.html -->
...
<div *ngFor="let question of questions"
class="form-row">
<app-question [question]="question"
[form]="form"></app-question>
</div>
...
위에서 볼 수 있듯이
app-question
는 ngFor
의 컬렉션을 순환하는 questions
안에 래핑되어 있습니다.이 구성 요소 안에는
QuestionBase
가 있습니다. 그것의 임무는 객체에 주어진 필드 유형에 따라 올바른 HTMLElement를 표시하는 것입니다.<!-- dynamic-form-question.component.html -->
<div [ngSwitch]="question.controlType">
<input *ngSwitchCase="'textbox'"
[formControl]="questionControl(index)"
[placeholder]="question.placeholder"
[attr.min]="question['min']"
[attr.max]="question['max']"
[attr.pattern]="question['pattern']"
[id]="questionId(index)"
[type]="question['type']">
<select [id]="question.key"
*ngSwitchCase="'dropdown'"
[formControl]="questionControl(index)">
<option value=""
disabled
*ngIf="!!question.placeholder"
selected>{{ question.placeholder }}</option>
<option *ngFor="let opt of question['options']"
[value]="opt.key">{{ opt.value }}</option>
</select>
...
</div>
ngSwitch
에 할당된 [attr.min]="question['min']"
속성이 있는 요소에 options
와 같은 속성 값을 전달하는 방식을 눈치챘을 것입니다.// question-dropdown.ts
import { QuestionBase } from './question-base';
export class TextboxQuestion extends QuestionBase<string> {
type: string;
min: number | string;
...
constructor(options: {} = {}) {
super(options);
this.type = options['type'] || 'text';
this.min = options['min'];
...
}
하지만
constructor
표시할 뿐만 아니라 FormControl
도 좋습니다! 이제 몇 가지 콘텐츠 프로젝션을 살펴보겠습니다.<!-- dynamic-form-question.component.html -->
<div *ngIf="question.iterable; else formTmpl">
<div *ngFor="let field of questionArray.controls;
let i=index; first as isFirst last as isLast">
<ng-container [ngTemplateOutlet]="formTmpl"
[ngTemplateOutletContext]="{index: i}"></ng-container>
<button *ngIf="question.iterable && questionArray.controls.length > 1"
(click)="removeQuestion(i)"
type="button">-</button>
<button *ngIf="question.iterable && isLast"
(click)="addQuestion()"
type="button">+</button>
</div>
</div>
이 라인
FormArray
은 <div *ngIf="question.iterable; else formTmpl">
의 컬렉션 또는 간단한 FormArray
를 표시하기로 결정하여 FormControl
로 래핑된 라인임을 알 수 있습니다. 이것이 우리가 어떤 반복 단계에 있는지 알 수 있는 유일한 방법이라는 점을 감안하여 현재 인덱스를 ng-template
로 전달하고 있습니다.<!-- dynamic-form-question.component.html -->
..
<ng-template #formTmpl
let-index="index">
<label [attr.for]="questionId(index)">{{ questionLabel(index) }}</label>
<div [ngSwitch]="question.controlType">
...
여기서 문제는 올바른
let-index="index"
요소(우리가 반복하고 있는 요소)와의 "링크"를 유지하는 것입니다. 왜냐하면 이 구성을 사용하면 question
에 questions
가 있기 때문입니다. a question
가 반복 가능한지 확인하는 유일한 방법은 question
의 iterable
속성을 확인하는 것이기 때문에 유형과 클래스는 이 시점에서 동일하게 유지됩니다.question
로 주입된 index
속성 덕분에 다음을 사용하여 <ng-template #formTmpl let-index="index">
에서 쉽게 검색할 수 있습니다.<ng-container [ngTemplateOutlet]="formTmpl"
[ngTemplateOutletContext]="{index: i}"></ng-container>
컬렉션의 올바른 반복 작업을 수행합니다.
데모 및 코드
모든 소스 코드는 Github에서 사용할 수 있으며 동적 양식의 놀라운 기능을 보고 싶다면 이미 데모를 사용할 수 있습니다!
최대화
/
각도 동적 형태
Angular를 사용하여 데이터에서 즉각적인 양식 생성
🔥 Demo available here 🔥
학점
사진 제공: Patrick Langwallner on Unsplash
다시 읽고 수정해 주셔서 감사합니다.
Reference
이 문제에 관하여(즉석에서 동적 Angular 양식 빌드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/max/build-dynamic-angular-forms-on-the-fly-4n3m
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(즉석에서 동적 Angular 양식 빌드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/max/build-dynamic-angular-forms-on-the-fly-4n3m텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)