Angular material table 每行都有可扩展的操作按钮

Angular material table with expandable action button at each row

我们正在努力实现 table 设计 POC,如下图所示,它具有以下特征。

问题在于以下功能

1) Expand and collapse behavior should be per row(Not for all rows at a time).
2) It should have value of particular row on click of any action from action-toolbar(i.e. Config, History, etc in image).

HTML

<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Symbol </th>
<td mat-cell *matCellDef="let element">
  <div [ngClass]="showFloatingButtons == true ? 'floating-pane-active' : 'floating-pane-deactive'"
    class="button-row">
    <mat-icon mat-fab *ngIf="showFloatingButtons == true" color="primary" class="floating-buttons">offline_pin
    </mat-icon>
    <mat-icon mat-fab *ngIf="showFloatingButtons == true" color="primary" class="floating-buttons">query_builder
    </mat-icon>
    <mat-icon mat-fab *ngIf="showFloatingButtons == true" color="primary" class="floating-buttons" disabled>restore
    </mat-icon>
    <mat-icon mat-fab *ngIf="showFloatingButtons == true" color="primary" class="floating-buttons">
      play_circle_filled</mat-icon>
    <mat-icon (click)="toggleFloat()" class="sky_blue">more_horiz</mat-icon>
  </div>
</td>

CSS

table {
  width: 100%;
}

.mat-form-field {
  font-size: 14px;
  width: 50%;
}

.mat-column-position {
  max-width: 100px;
  min-width: 10px;
}

.mat-column-name {
  max-width: 100px;
  min-width: 10px;
}

.example-trigger {
  display: inline-block;
}

.floating-buttons {
  z-index: 2;
  // position: fixed;
  overflow: auto;
  top: auto;
  left: auto;
}

.floating-pane-active {
  background-color: rgba(215, 228, 230, 0.39);
  border-top-left-radius: 25px;
  border-bottom-left-radius: 25px;
  background-position: right;
  background-repeat: repeat;
}

.floating-pane-deactive {
  background-color: rgba(215, 228, 230, 0.39);
  border-top-left-radius: 25px;
  border-bottom-left-radius: 25px;
  background-position: right;
  background-repeat: repeat;
  width: 30px;
}

.button-row {
  align-items: center;
  justify-content: space-around;
}

.action-buttons {
  width: 20px;
}

.sky_blue {
  color: skyblue;
}

.mat-column-symbol {
  word-wrap: break-word !important;
  white-space: unset !important;
  flex: 0 0 10% !important;
  width: 10% !important;
  overflow-wrap: break-word;
  word-wrap: break-word;

  word-break: break-word;

  -ms-hyphens: auto;
  -moz-hyphens: auto;
  -webkit-hyphens: auto;
  hyphens: auto;
  text-align: right;
}

TS(只放重要的一行)

showFloatingButtons = false;

Collapsed column icons

Expanded column icons

仅供参考:我已将此 link 引用为可扩展行 table。

更多内容请查找演示代码here on stackblitz

PS:这里的主要问题是实现一次展开单行图标

您的第一个问题很简单,您对 show/hide 个元素使用相同的变量,因此它们 appear/disappear 在一起是一种自然行为。您必须创建一个 table 来存储每一行​​的状态(扩展或未扩展),为此我创建了这个 table 并在 ngOnInit:

中对其进行了初始化
expanded = [];
for(var i: number = 0; i < ELEMENT_DATA.length; i++) {
    this.expanded[i] = false;
}

然后我更改了您的 toggleFunction 以更改 tables 列的值:

toggleFloat(i:number) {
    this.expanded[i] = !this.expanded[i];
}

并且在 HTML 中,我更改了 *ngIf 条件以使用新的 table 而不是旧变量:

  <ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Symbol </th>
    <td mat-cell *matCellDef="let element; let i = index">
      <div [ngClass]="expanded[i] == true ? 'floating-pane-active' : 'floating-pane-deactive'"
        class="button-row">
        <mat-icon mat-fab *ngIf="expanded[i] == true" color="primary" class="floating-buttons">offline_pin
        </mat-icon>
        <mat-icon mat-fab *ngIf="expanded[i] == true" color="primary" class="floating-buttons">query_builder
        </mat-icon>
        <mat-icon mat-fab *ngIf="expanded[i] == true" color="primary" class="floating-buttons" disabled>restore
        </mat-icon>
        <mat-icon mat-fab *ngIf="expanded[i] == true" color="primary" class="floating-buttons">
          play_circle_filled</mat-icon>
        <mat-icon (click)="toggleFloat(i)" class="sky_blue">more_horiz</mat-icon>
      </div>
    </td>
  </ng-container>

Here is the stackblitz,解决了你的第一个问题,虽然我不太明白你的第二个问题是什么。

对于列表中的第 4 项,解决此问题的一种方法是向每个元素本身添加一个布尔值 属性(在我的示例中称为 expand)以指定它是展开还是展开不,像这样...

{ id: 1, startDate: today, endDate: today, position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H', expand: false }

然后,您可以通过element变量(*matCellDef="let element")在模板中访问这个新的属性。

但首先要确保在调用点击函数时传递了元素,就像这样... <mat-icon (click)="toggleFloat(element)" class="sky_blue">more_horiz</mat-icon>

并更改 toggleFloat 函数以更改此元素的元素扩展 属性 而不是 showFloatingButtons,像这样...

  toggleFloat(element) {
    element.exapand = !element.exapand;
    console.log('show:' + element.exapand);
  }

完成后,您可以修复模板以开始使用元素展开 属性 而不是组件的,方法是将符号列的所有 *ngIf 中的 showFloatingButtons 替换为 element.exapand,例如这...

  <ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Symbol </th>
    <td mat-cell *matCellDef="let element">
      <div [ngClass]="element.exapand ? 'floating-pane-active' : 'floating-pane-deactive'"
        class="button-row">
        <mat-icon mat-fab *ngIf="element.exapand" color="primary" class="floating-buttons">offline_pin
        </mat-icon>
        <mat-icon mat-fab *ngIf="element.exapand" color="primary" class="floating-buttons">query_builder
        </mat-icon>
        <mat-icon mat-fab *ngIf="element.exapand" color="primary" class="floating-buttons" disabled>restore
        </mat-icon>
        <mat-icon mat-fab *ngIf="element.exapand" color="primary" class="floating-buttons">
          play_circle_filled</mat-icon>
        <mat-icon (click)="toggleFloat(element)" class="sky_blue">more_horiz</mat-icon>
      </div>
    </td>
  </ng-container>

我不清楚你想要解决第 5 项中的问题,但如果你要显示特定于该元素的内容,请遵循与扩展功能相同的原则。

作为旁注,由于您正在处理一个布尔值,因此无需像这样测试相等性 *ngIf="showFloatingButtons == true",我们可以简单地这样做 *ngIf="showFloatingButtons".

在此处查看完整的解决方案 https://stackblitz.com/edit/angular-1tgnev?file=src/app/app.component.html