как динамически генерировать formControl - PullRequest
0 голосов
/ 23 сентября 2019

Я хотел бы иметь возможность динамически создавать мои переменные formControl, которые соответствуют именам моих столбцов моего объекта Table, без необходимости жесткого написания в методе createInput (), который я вставляю в свой formArray.

Я пробовал это, но это не работает:

import { Component, OnInit } from '@angular/core';
import { ParameterService } from '../service/parameter.service';
import { Table } from '../model/table.model';
import { FormControl, FormGroup, FormBuilder, FormArray } from '@angular/forms';
import { DomSanitizer } from '@angular/platform-browser';
import { Typpar } from '../model/typpar.model';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

  typpar: Typpar;
  table: Table;
  fileUrl: any;

  formGroup: FormGroup;
  inputRows: FormArray;

  numberOfLineForm: FormGroup;

  // On injecte une instance de FormBuilder et de ParameterService en dépendance de notre component
  constructor(public ps: ParameterService, private formBuilder: FormBuilder, private sanitizer: DomSanitizer) { }

  ngOnInit() {
     // initialize our form using FormBuilder in the ngOnInit hook.
     // We’ll create a formGroup that allows the user to add new inputRows dynamically:
    this.formGroup = this.formBuilder.group({
      inputRows: this.formBuilder.array([this.createInput()])
    });
    console.log(this.formGroup);

    this.numberOfLineForm = this.formBuilder.group({
      numberOfLine: ['']
    });
    console.log(this.numberOfLineForm);

    this.ps.getAllColumns().subscribe(res => {
      this.table = res;
      this.createInput();
      console.log(this.table);
    });

    this.ps.getAllParams().subscribe(res => {
      this.typpar = res;
      console.log(res);
    });
 }

  // Permet de récupéer formData dans la vue qui est une instance de FormArray
  get formData() { return this.formGroup.get('inputRows') as FormArray; }

  // method to create a form group as the first inputRow in our array
  createInput(): FormGroup {
    // Comment récupérer le bon nombre de formControl qui correspondent
    // aux nom de mes columns de mon objet Table sans avoir à les mettres en dure
    console.log(this.table);
    if (this.table && this.table.columns.map) {
      this.table.columns.map((column) => {
        this.formGroup.addControl(column.name, new FormControl(''));
      });
    }
    return this.formGroup;

Вот мой html компонента панели управления:

    <!--Dashboard-->
<section class="section_4">
<!-- ON A NOMMÉ LE FORMULAIRE "orderForm" dans le app.component.ts -->
<!-- ON utilise la directive [formGroup]='orderForm pour le lier' -->
<form [formGroup]='formGroup' (ngSubmit)='submitForm(formGroup.value)' class="table">
    <div class="section_5">
        <div class="line">
            <div class="columnName" *ngFor="let column of table?.columns">{{ column.name }}</div>
        </div>
        <!-- 
        ICI LA DIRECTIVE formArrayName='items' permet de cibler items 
        qui est déclaré comme un formArray dans app.component.ts

        formData provient de : get formData() { return <FormArray>this.orderForm.get('items'); }
    -->
        <div formArrayName="inputRows" *ngFor="let inputRow of formData.controls; let i = index; let c = count">
            <div class="line" [formGroupName]="i" id="inputRow">
                <!-- <span>{{i+1}} </span> -->
                <ng-container *ngFor="let column of table?.columns">
                    <select *ngIf="column?.dropdown; else noDropdown" formControlName="{{column.name}}">
                        <option *ngFor="let param of column?.parameters;" value="{{param.id}}">{{param.libelle}}></option>
                    </select>
                    <ng-template #noDropdown>
                        <input class="myInput" formControlName="{{column.name}}" type="{{ column.type }}" name="{{column.name}}_{{i}}" maxLength="{{ column.length }}" required="{{ column.nullable }}" value="{{ column.dataDefault }}" placeholder=" ">
                    </ng-template>
                </ng-container>
                <span><img title="Supprimer la ligne " *ngIf="c > 1" (click)="deleteInputLine($event, i)" id="deleteIcon" src="../../assets/img/cancel.png" /></span>
            </div>
        </div>
    </div>
    <br>
    <hr>
    <div class="button">
        <button type="button" class="btn btn-info" (click)="addInputRow($event)">Ajouter une ligne</button>
        <!-- <button type="submit" class="btn btn-info">Envoyer</button> -->
        <a [href]="fileUrl" (click)="downloadSqlQuery()" download="sql_query.txt" class="btn btn-secondary btn-lg active" role="button" aria-pressed="true">DownloadFile</a>
    </div>
</form>

ошибка консоли:

enter image description here

1 Ответ

1 голос
/ 23 сентября 2019

Ваш синтаксис отключен в нескольких местах.Не звоните createInput() внутри формации.Тогда вы не отправляете значения в свой формат, а вместо этого отправляете их в группу форм.Затем вы перебираете и шаблон, и ваш массив table.columns в шаблоне.Вам следует просто перебрать форматирование и, основываясь на индексе, вы можете обратиться к массиву table.columns.Вот сокращенный минимальный пример вашего кода.Говоря об этом, вы всегда должны предоставлять минимальный образец проблемы, с которой вы сталкиваетесь (совет для будущих вопросов).Но вернемся к вопросу, вот некоторые исправления:

ngOnInit() {
  this.formGroup = this.formBuilder.group({
    inputRows: this.formBuilder.array([]) // don't call createInput!
  });
}

Ваша функция createInput должна вместо этого добавить новые группы форм в formarray:

get formData() { return this.formGroup.get('inputRows') as FormArray; }

// method to create a form group as the first inputRow in our array
createInput() {
  if (this.table && this.table.columns.length) {
    this.table.columns.map((column) => {
      this.formData.push(
        this.formBuilder.group({
          // add dynamic name with brackets
          [column.name]: ['']
        })
      );
  }
})

И, наконец, выполнить итерацию в шаблоне:

<form [formGroup]='formGroup' (ngSubmit)='submitForm(formGroup.value)'>
  <div formArrayName="inputRows" *ngFor="let inputRow of formData.controls; let i = index;">
    <ng-container [formGroupName]="i" >
      <input [formControlName]="table.columns[i].name" >
    </ng-container>
  </div>
</form>

ДЕМО: STACKBLITZ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...