You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Material实现FormArray输入项按4列每行展示

Solution to Angular Material FormArray Layout Issue (4 Columns with 4 Inputs Each)

Looking at your code, the problem is that you're rendering all 16 FormArray controls as individual rows, which stacks them vertically (giving the impression they're all in one column). To fix this, we need to group the 16 controls into 4 columns (each containing 4 inputs) and adjust the HTML layout accordingly.

Step 1: Add a Getter to Group FormArray Controls into Columns

First, add a getter in your component to split the FormArray's controls into 4 columns (each with 4 items):

get destColumns(): FormGroup[][] {
  const destControls = (this.combinationForm.get('dest') as FormArray).controls as FormGroup[];
  const columnCount = 4; // Since you have 4 regions
  const columns: FormGroup[][] = [];

  // Split the 16 controls into 4 columns of 4
  for (let i = 0; i < columnCount; i++) {
    const startIndex = i * columnCount;
    columns.push(destControls.slice(startIndex, startIndex + columnCount));
  }

  return columns;
}

Step 2: Rewrite the HTML Layout

Update your template to render the grouped columns instead of individual controls. We'll use a horizontal flex container for the columns, and each column will hold 4 vertical input fields:

<div *ngIf="enableCombinationDirective">
  <div class="h1">Add Prices</div>
  <div [formGroup]="combinationForm">
    <!-- Horizontal container for 4 columns -->
    <div fxLayout="row" fxLayoutAlign="space-between stretch" style="gap: 16px;">
      <!-- Loop through each column -->
      <div fxFlex="25%" *ngFor="let column of destColumns; let colIndex = index">
        <!-- Loop through the 4 items in the column -->
        <div 
          *ngFor="let item of column; let rowIndex = index" 
          [formGroupName]="colIndex * 4 + rowIndex"
          style="margin-bottom: 16px;"
        >
          <mat-form-field appearance="outline" style="width: 100%;">
            <mat-label>{{ item.get('combinationTitle').value }}</mat-label>
            <input 
              matInput 
              type="number" 
              formControlName="price" 
              placeholder="Enter Price" 
            />
            <mat-checkbox formControlName="isActive" matSuffix></mat-checkbox>
          </mat-form-field>
        </div>
      </div>
    </div>

    <div fxLayout="row" style="margin-top: 24px;">
      <button fxFlex="100" mat-raised-button color="primary" (click)="save()">
        Save Changes
      </button>
    </div>
  </div>
</div>

Key Fixes Explained:

  1. Column Grouping: The destColumns getter splits your 16 FormArray controls into 4 logical columns, matching your 4-region requirement.
  2. Horizontal Layout: The outer fxLayout="row" container arranges the 4 columns side-by-side, with fxFlex="25%" ensuring each column takes equal width.
  3. Correct Form Group Index: We calculate the correct formGroupName using colIndex * 4 + rowIndex to map back to the original FormArray indices (0-15).
  4. Cleaner Structure: Removed unnecessary nested flex containers and adjusted spacing to make the layout consistent.

Optional Cleanup Note

I noticed your getRegionsCombinations function declares a selectedRegion variable that isn't used later. You can safely remove that line to clean up your code:

// Remove this unused line:
// let selectedRegion: IRegion[] = this.regions.filter((data) => data.id === region);

内容的提问来源于stack exchange,提问作者Ehsan Nissar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:27:40