Angular에서 계층 구조를 가진 JSON에서 입력 양식을 동적으로 생성합니다.

Angular에서 계층 구조를 가진 JSON에서 입력 양식을 동적으로 생성하는 코드를 GitHub에 게시했습니다.

GitHub는 이쪽
dynamic-form-builder-recursive

화면 샘플



※들여쓰기로 계층 구조를 나타내고 있습니다 입력 양식 설정용 JSON fields: any[] = [ { "id": "text1", "text": "text1", "type": "text" }, { "id": "radio1", "text": "radio1", "type": "radio", "options": [ { "text": "option1", "value": "option1" }, { "text": "option2", "value": "option2" }, { "text": "option3", "value": "option3" } ] }, { "id": "checkbox1", "text": "checkbox1", "type": "checkbox", "options": [ { "text": "option1", "value": "option1" }, { "text": "option2", "value": "option2" }, { "text": "option3", "value": "option3" } ] }, { "id": "text2", "text": "text2", "type": "text", "item": [ { "id": "text2-1", "text": "text2-1", "type": "text", "item": [ { "id": "text2-1-1", "text": "text2-1-1", "type": "text", "item": [ { "id": "text2-1-1-1", "text": "text2-1-1-1", "type": "text", "item": [ { "id": "text2-1-1-1-1", "text": "text2-1-1-1-1", "type": "text" } ] } ] } ] } ] } ]; 참고하신 코드 Angular 6 dynamic from builder with Reactive Forms.

참고라고 할까 거의 copipe입니다만 www

포인트



입력 양식을 설정하는 JSON과 동일한 계층 구조의 FormGroup 만들기


  ngOnInit() {
    // FormControl生成
    let fieldsCtrls:any = this.walkJSON(this.fields, function(item) {
      let fieldsCtrl: any = {};
      if (item.type != 'checkbox') {
        fieldsCtrl = new FormControl(item.value || '', Validators.required)
      } else {
        let opts = {};
        for (let opt of item.options) {
          opts[opt.value] = new FormControl('');
        }
        fieldsCtrl = new FormGroup(opts)
      }
      return fieldsCtrl;
    });

    this.form = new FormGroup(fieldsCtrls);
  }

  walkJSON(data, callback){
    const formGroup: any = {};
    data.forEach(item => {

      formGroup[item.id] = callback(item);
      if (item.item) {
        formGroup[item.id + '_child'] = new FormGroup(this.walkJSON(item.item, callback));
      }
    });

    return formGroup;
  }

설정 항목 안에 아이를 가지는 경우가 있으므로, 재귀적으로 처리합니다.
FormGroup에는 반드시 이름을 붙여야 하기 때문에, 부모의 ID에 「_child」를 붙이고 있습니다. (다사이므로 어떻게든 하고 싶습니다만...)

템플릿 측에서 구성 요소를 재귀 적으로 호출


  template: `
  <ng-container [formGroup]="form">
    <ng-container [ngSwitch]="field.type">
      <div class="child">
        <textbox *ngSwitchCase="'text'" [field]="field" [form]="form"></textbox>
        <checkbox *ngSwitchCase="'checkbox'" [field]="field" [form]="form"></checkbox>
        <radio *ngSwitchCase="'radio'" [field]="field" [form]="form"></radio>
        <div *ngIf="!isValid && isDirty">{{field.text}} is required</div>
      </div>
    </ng-container>
    <!-- 子を持つ場合 -->
    <ng-container  *ngIf="field.item">
    <div *ngFor="let childField of field.item" class="parent">
        <field-builder [field]="childField" [form]="form.controls[field.id + '_child']"></field-builder>
    </div>
    </ng-container>
  </ng-container>
  `

field-builder 구성 요소에서 field-builder 구성 요소를 추가로 호출합니다.
이 때 동일한 계층 구조의 FromGroup을 지정합니다.

감상



Angular는, 설정 파일로부터 화면을 생성하는 것 같은 것에는 그다지 적합하지 않을까 생각했지만, 제대로 구조가 준비되어 있었다.
학습 비용은 높지만, 익숙해지면 여러가지 할 것 같은 생각이 듭니다.

좋은 웹페이지 즐겨찾기