繁体   English   中英

如何在 mat-table 的可扩展行中构建动态表单?

[英]How to build a dynamic form in a mat-table's expandable row?

我正在尝试构建一个允许我在其上执行多项任务的表; 其中,我正在尝试实现在那里编辑记录信息的能力。

我的想法是像往常一样创建 mat-table,用一个额外的可扩展行来显示一个小表单,其中包含我可以编辑的字段和一个按钮来保存更改和更新表。 但是我不确定如何实际构建它,因为我不确定如何为表中的每一行构建反应式表单; 我将无法在组件 TypeScript 文件中声明它,例如:

rowForm = new FormGroup({
            control1: new FormControl() 
         })

因为我需要它用于表中的每条记录。

 <table mat-table matSort [dataSource]="dataSource" class="table table-borderless admin-users-table" multiTemplateDataRows>
     <ng-container matColumnDef="name">
         <th mat-header-cell *matHeaderCellDef mat-sort-header> NAME </th>
         <td mat-cell *matCellDef="let user">
             <a href="javascript:" [routerLink]="['/setup/users', user._id]">
                 {{ user.name }}
             </a>
         </td>
     </ng-container>

     <ng-container matColumnDef="email">
         <th mat-header-cell *matHeaderCellDef mat-sort-header> EMAIL </th>
         <td mat-cell *matCellDef="let user">
             {{ user.email }}
         </td>
     </ng-container>

     <ng-container matColumnDef="id">
         <th mat-header-cell *matHeaderCellDef> USER ID </th>
         <td mat-cell *matCellDef="let user">
             {{ user._id }}
         </td>
     </ng-container>

     <ng-container matColumnDef="org">
         <th mat-header-cell *matHeaderCellDef mat-sort-header> ORGANIZATION </th>
         <td mat-cell *matCellDef="let user">
             {{ user.organization.name }}
         </td>
     </ng-container>
                
     <!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
     <ng-container matColumnDef="expandedDetail">
         <td mat-cell *matCellDef="let element" class="py-0" [attr.colspan]="columnsToDisplay.length">
             <div class="user-element-detail"
                        [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
                  <div class="user-element-diagram">
                      <div class="user-element-position"> {{element.position}} </div>
                      <div class="user-element-symbol"> {{element.symbol}} </div>
                      <div class="user-element-name"> {{element.name}} </div>
                      <div class="user-element-weight"> {{element.weight}} </div>
                  </div>
                  <div class="user-element-description">
                        {{element.description}}
                     <span class="user-element-description-attribution"> -- Wikipedia </span>
                  </div>
             </div>
         </td>
      </ng-container>


      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let element; columns: displayedColumns;"
                    class="user-element-row"
                    [class.user-expanded-row]="expandedElement === element"
                    (click)="expandedElement = expandedElement === element ? null : element">
      </tr>
      <tr mat-row *matRowDef="let row; columns: ['expandedDetail']"></tr>
</table>

关于我应该如何解决这个问题或者是否有更优化的方法来完成这种功能的任何想法?

这个想法是你的“数据源”有一个表格。 例如,您创建一个 function 之类的

createForm(data:any)
  {
    return new FormGroup({
      name:new FormControl(data.name),
      weight:new FormControl(data.weight),
      symbol:new FormControl(data.symbol),
      position:new FormControl(data.position),
    })
  }

你的数据就是

dataSource = ELEMENT_DATA.map(x=>({...x,form:this.createForm(x)}));

在可扩展行中,添加表单和两个按钮“确定”“取消”

    <form [formGroup]="element.form">
      <input formControlName="name"/>
      <button (click)="element.name=element.form.value.name;
                       expandedElement=null">ok</button>
      <button (click)="element.form.patchValue(element);
                       expandedElement=null">cancel</button>
    </form>

你可以在stackblitz中看到

注意:管理的另一个选项是“就地编辑”,如本 SO

关于注释的更新,我们可以将 ELEMENT_DATA 转换为 FormArray

dataSource = new FormArray(ELEMENT_DATA.map(x=>this.createForm(x)));

然后我们在索引处添加了一个辅助 function 以返回 formGroup

  getGroup(index:number)
  {
    return this.dataSource.at(index) as FormGroup
  }

最后一个 if 使用,例如getGroup(i).get('position')获取控件并用作 dataSource dataSource.controls

<table mat-table
   [dataSource]="dataSource.controls" multiTemplateDataRows
   class="mat-elevation-z8">
<ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
    <th mat-header-cell *matHeaderCellDef> {{column}} </th>
    <1--see that we use let i=datIndex becaouse is a multiTemplateDataRows-->
    <td mat-cell *matCellDef="let element;let i=dataIndex"> {{getGroup(i).get(column).value}} </td>
  </ng-container>
....
<table>

在可扩展行中:

<form [formGroup]="getGroup(i)">
  <input formControlName="name"/>
</form>

好吧,唯一的是我们没有“确定”和“取消”按钮,当更改输入时,您会看到数据如何自动更改

看到一个新的堆栈闪电战

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM