从表单生成 table

Generate table from form

我有一个表单组:

public transactionOrRefundRequestForm: FormGroup = new FormGroup({
    SaleRequest: new FormGroup({
      Header: new FormGroup({
        Type: new FormControl('', [Validators.required]),
        Class: new FormControl('', [Validators.required]),
        MessageCategory: new FormControl('', [Validators.required]),
        Sale: new FormControl('', [Validators.required]),
        ID: new FormControl('', [Validators.required]),
        Protocol: new FormControl('', [Validators.required]),
        Service: new FormControl('', [Validators.pattern(/^-?(0|[1-9]\d*)?$/), Validators.maxLength(10)]),
      }),
      PaymentRequest: new FormGroup({
        SaleData: new FormGroup({
          SaleID: new FormGroup({
            TransactionID: new FormControl(''),
            TimeStamp: new FormControl('')
          })
        }),
        PaymentTransaction: new FormGroup({
          Amounts: new FormGroup({
            Currency: new FormControl(''),
            RequestedAmount: new FormControl('')
          }),
          ProprietaryTags: new FormGroup({
            Print: new FormControl('')
          })
        }),
        PaymentData: new FormGroup({
          Type: new FormControl('')
        })
      }),
    })
  });

我需要从中创建一个 table。像这样:

<form [formGroup]="transactionOrRefundRequestForm">
    <div class="request-form" formGroupName="SaleToPOIRequest">
      <div formGroupName="MessageHeader">
        <table>
          <thead>
          <tr>
            <td>
              <span>MessageHeader</span>
            </td>
            <td class="form-buttons">
              <button color="primary" mat-raised-button (click)="onAddField('SaleToPOIRequest.MessageHeader')">Add Field</button>
              <button color="primary" mat-raised-button>Add Category</button>
            </td>
          </tr>
          </thead>
          <tbody>
          <tr>
            <td>
              <mat-form-field>
                <mat-label>MessageType</mat-label>
                <mat-select formControlName="MessageType">
                  <mat-option [value]="'Request'">Request</mat-option>
                  <mat-option [value]="'Response'">Response</mat-option>
                </mat-select>
              </mat-form-field>
            </td>
          </tr>
          <tr>
            <td>
              <mat-form-field>
                <mat-label>MessageClass</mat-label>
                <mat-select formControlName="MessageClass">
                  <mat-option [value]="'Service'">Service</mat-option>
                  <mat-option [value]="'Device'">Device</mat-option>
                </mat-select>
              </mat-form-field>
            </td>
          </tr>
          <tr>
            <td>
              <mat-form-field>
                <mat-label>MessageCategory</mat-label>
                <mat-select formControlName="MessageCategory">
                  <mat-option [value]="'Payment'">Payment</mat-option>
                  <mat-option [value]="'Input'">Input</mat-option>
                  <mat-option [value]="'Diagnosis'">Diagnosis</mat-option>
                  <mat-option [value]="'Reconciliation'">Reconciliation</mat-option>
                  <mat-option [value]="'TransactionStatus'">TransactionStatus</mat-option>
                  <mat-option [value]="'Reversal'">Reversal</mat-option>
                  <mat-option [value]="'Admin'">Admin</mat-option>
                  <mat-option [value]="'Abort'">Abort</mat-option>
                </mat-select>
              </mat-form-field>
            <td>
          </tr>
          <tr>
            <td>
              <mat-form-field>
                <mat-label>SaleID</mat-label>
                <input formControlName="SaleID" matInput>
              </mat-form-field>
            </td>
          </tr>
          <tr>
            <td>
              <mat-form-field>
                <mat-label>POIID</mat-label>
                <input formControlName="POIID" matInput>
              </mat-form-field>
            </td>
          </tr>
          <tr>
            <td>
              <mat-form-field>
                <mat-label>ProtocolVersion</mat-label>
                <input formControlName="ProtocolVersion" matInput>
              </mat-form-field>
            </td>
          </tr>
          <tr>
            <td>
              <mat-form-field>
                <mat-label>ServiceID</mat-label>
                <input  formControlName="ServiceID" matInput>
              </mat-form-field>
            </td>
            <td>
              <button (click)="onSetRandomServiceID()" color="primary" mat-raised-button>Generate Random</button>
            </td>
          </tr>
          </tbody>
        </table>
      </div>
      <div formGroupName="PaymentRequest">
        <table>
          <thead>
          <tr>
            <td>
              <span>PaymentRequest</span>
            </td>
            <td class="form-buttons">
              <button color="primary" mat-raised-button>Add Field</button>
              <button color="primary" mat-raised-button>Add Category</button>
            </td>
          </tr>
          </thead>
        </table>
        <div formGroupName="SaleData">
          <table>
            <thead>
            <tr>
              <td>
                <span>SaleData</span>
              </td>
              <td class="form-buttons">
                <button color="primary" mat-raised-button>Add Field</button>
                <button color="primary" mat-raised-button>Add Category</button>
              </td>
            </tr>
            </thead>
            <tbody></tbody>
          </table>
          <div formGroupName="SaleTransactionID">
            <table>
              <thead>
              <tr>
                <td>
                  <span>SaleTransactionID</span>
                </td>
                <td class="form-buttons">
                  <button color="primary" mat-raised-button>Add Field</button>
                  <button color="primary" mat-raised-button>Add Category</button>
                </td>
              </tr>
              </thead>
              <tbody>
              <tr>
                <td>
                  <mat-form-field>
                    <mat-label>TransactionID</mat-label>
                    <input formControlName="TransactionID" matInput>
                  </mat-form-field>
                </td>
              </tr>
              <tr>
                <td>
                  <mat-form-field>
                    <mat-label>TimeStamp</mat-label>
                    <input formControlName="TimeStamp" matInput>
                  </mat-form-field>
                </td>
              </tr>
              </tbody>
            </table>
          </div>
        </div>
        <div formGroupName="PaymentTransaction">
          <table>
            <thead>
            <tr>
              <td>
                <span>PaymentTransaction</span>
              </td>
              <td class="form-buttons">
                <button color="primary" mat-raised-button>Add Field</button>
                <button color="primary" mat-raised-button>Add Category</button>
              </td>
            </tr>
            </thead>
            <tbody></tbody>
          </table>

我想知道是否有办法以某种方式循环它,如果它是一个组创建一个 div with table in int 就像上面的例子一样,如果它是一个控件创建只是带有输入的 tr。我想到了一种实现此目的的方法,即通过 json 并尝试从中生成它,但我失败了。

如果需要,我稍后会创建一个 fiddle。

此外,如果它能够为我选择的某些控件生成 select 元素,那就太好了。

所以我递归地生成了表单,这样我就可以自由地在表单中添加和删除任何项目,解决方案在这里:

这就是我从表单递归生成 table 的方式:

<ng-template #formCategoryTemplate let-formCategory>
    <div [formGroup]="getFormGroup(formCategory)" class="request-form">
      <table>
        <thead>
        <span>{{toCategory(formCategory).name}}</span>
        </thead>
      </table>

      <ng-container *ngFor="let formEntry of toCategory(formCategory).entries">
        <ng-container *ngIf="isCategory(formEntry)">
          <ng-container [ngTemplateOutlet]="formCategoryTemplate"
                        [ngTemplateOutletContext]="{$implicit: toCategory(formEntry)}">
          </ng-container>
        </ng-container>

        <tr class="input" *ngIf="isInput(formEntry)">
          <td>
            <mat-form-field appearance="outline" class="full-width">
              <mat-label>{{toInput(formEntry).name}}</mat-label>
              <input [formControl]="getFormControl(toInput(formEntry))" matInput>
            </mat-form-field>
          </td>
        </tr>
      </ng-container>
    </div>
  </ng-template>

  <div>
    <form [formGroup]="rebootRequestForm" *ngIf="formStructure">
      <ng-container [ngTemplateOutlet]="formCategoryTemplate"
                    [ngTemplateOutletContext]="{$implicit: formStructure}">
      </ng-container>
    </form>
  </div>