【问题标题】:CAN NOT expand Angular Material table不能展开角材料表
【发布时间】:2019-05-12 18:42:42
【问题描述】:

在过去的 2 周里,我一直在尝试让这段代码正常工作。我搜索并尝试了Philipp Kief 的解决方案,这是我可以部分理解的解决方案。我是新人。

我还研究了这些其他解决方案。 Ho Wei Lip 2Ho Wei Lip 3

不幸的是,我被卡住了,我不知道为什么表格没有展开。我没有收到错误,但似乎(click)MatRipple 似乎做出了回应。我也试过了,material expansion panel,但似乎离题了。有人能指出我正确的方向吗?谢谢。

import { Component, OnInit, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DataSource } from '@angular/cdk/collections';
import { Incident } from './interface';
import {
  MatSort,
  MatTableDataSource,
  ICON_REGISTRY_PROVIDER,
  MatPaginator
} from '@angular/material';
import {
  animate,
  state,
  style,
  transition,
  trigger
} from '@angular/animations';
import { switchMap, concatMap } from 'rxjs/operators';
import { interval } from 'rxjs';
import { timer } from 'rxjs/observable/timer';

@Component({
  selector: 'app-incident',
  templateUrl: './incident.component.html',
  styleUrls: ['./incident.component.css'],
  animations: [
    trigger('detailExpand', [
      state(
        'collapsed',
        style({ height: '0px', minHeight: '0', visibility: 'hidden' })
      ),
      state('expanded', style({ height: '*', visibility: 'visible' })),
      transition(
        'expanded <=> collapsed',
        animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
      )
    ])
  ]
})
export class IncidentComponent implements OnInit {
  constructor(private http: HttpClient) {}
  @ViewChild(MatSort) sort: MatSort;
  private serviceUrl = 'http://localhost:3001/api-incidents/55';

  FIVE_MINUTES = 5 * 60 * 1000;
  panelOpenState = false;
  incidents: Incident;
  incidentParseArray: any;
  incidents_sortable: any;
  displayedColumns: string[] = [
    // 'statusIcon',
    'incident'
    // 'INCIDENT_TYPE',
    // 'MODIFICATION_DATE',
    // 'prognosisIcon'
  ];
  dataSource = new MatTableDataSource<Incident>(this.incidentParseArray);

  expandedElement: any;
  isExpansionDetailRow = (i: number, row: Object) =>
    row.hasOwnProperty('detailRow')

  ngOnInit() {
    timer(0, this.FIVE_MINUTES).subscribe(() => {
      this.http.get<Incident>(this.serviceUrl).subscribe(response => {
        this.incidents = response;
        const incidentArray = Object.values(this.incidents);
        // console.log('array ===> ', incidentArray);
        this.incidentParseArray = incidentArray.map(
          ({
            INCIDENT_NAME,
            eStatus,
            eSTATUS_COLOR,
            INCIDENT_TYPE,
            ePROGNOSIS,
            ePROGNOSIS_COLOR,
            MODIFICATION_DATE
          }) => {
            const [incident, aux] = INCIDENT_NAME.split(/-\s+/, 2);
            const [status, active] = eStatus.split(/-\s+/, 2);
            const [junk0, statusColor, junk1] = eSTATUS_COLOR.split(/\./, 3);
            const [junk2, prognosisColor, junk3] = ePROGNOSIS_COLOR.split(
              /\./,
              3
            );
            const statusIcon = assignStatusIcon(statusColor);
            const prognosisIcon = assignPrognosisIcon(ePROGNOSIS);
            const prognosisColorText = assignPrognosisColor(prognosisColor);
            const statusColorText = assignStatusColor(statusColor);

            return {
              incident,
              status,
              statusColor,
              statusIcon,
              statusColorText,
              prognosisColor,
              prognosisColorText,
              INCIDENT_TYPE,
              ePROGNOSIS,
              prognosisIcon,
              MODIFICATION_DATE
            };
          }
        );
      });
    });
  }
}

function assignStatusIcon(color) {
  let icon = '';
  if (color === 'gray') {
    icon = 'brightness_1';
  } else if (color === 'green') {
    icon = 'brightness_1';
  } else {
    icon = 'broken_image';
  }
  return icon;
}

function assignStatusColor(color) {
  let pcolor = '';
  if (color === 'gray') {
    pcolor = 'grey-text';
  } else if (color === 'green') {
    pcolor = '#00c853 green-text accent-4';
  } else {
    pcolor = 'black-text';
  }
  return pcolor;
}

function assignPrognosisIcon(str) {
  let icon = '';
  if (str === 'Monitoring') {
    icon = 'remove_red_eye';
  } else if (str === 'Response') {
    icon = 'directions_walk';
  } else {
    icon = 'broken_image';
  }
  return icon;
}

function assignPrognosisColor(color) {
  let pcolor = '';
  if (color === 'grey') {
    pcolor = 'grey-text';
  } else if (color === 'red') {
    pcolor = 'red-text';
  } else {
    pcolor = 'black-text';
  }
  return pcolor;
}

这是我的模板。

<mat-table #table [dataSource]="incidentParseArray" matSort class="z-depth-2 table-font-size
    mat-display-10">
    <ng-container matColumnDef="incident">
        <th mat-header-cell *matHeaderCellDef class="table-font-size" [ngClass]="'customWidthClass'">
            INCIDENT </th>
        <td mat-cell *matCellDef="let element" class="table-font-size mat-cell" [ngClass]="'customWidthClass'">
            {{element.incident}} </td>
    </ng-container>
    <!-- EXPANDED CONTENT  - TEST -->
    <ng-container matColumnDef="expandedDetail">
        <mat-cell *matCellDef="let element">
            The symbol for {{element.INCIDENT_TYPE}} is
            TEST TEST TEST
        </mat-cell>
    </ng-container>

    <mat-row *matRowDef="let row; columns: ['expandedDetail']; when: isExpansionDetailRow"
        [@detailExpand]="row.element == expandedElement ? 'expanded' : 'collapsed'"
        style="overflow: hidden">
    </mat-row>


    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row mat-row *matRowDef="let row; columns: displayedColumns;"
        matRipple
        class="element-row"
        [class.expanded]="expandedElement == row"
        (click)="expandedElement= row">

    </mat-row>

</mat-table>

【问题讨论】:

  • 不是答案,但 MatTableDataSource 接受 client-side 数据数组,即如果您将 dataSource 替换为硬编码数组,它应该会显示。遵循this 教程,尤其是创建一个单独的基于 Observable 的服务,以将数据获取分离为 observable。您是否从材料网站here 上的示例开始。他们有&lt;th mat-header-cell 而不是&lt;mat-header-row
  • 还要确保你已经导入了BrowserAnimationsModule,就像在这个Stackblitz中一样

标签: angular angular-material expandable-table


【解决方案1】:

这项工作的关键是when: isExpansionDetailRow,它调用以下函数表达式...它实质上为detailRow 的属性评估MatTableDataSource 中的每个对象并返回true(如果存在)。

isExpansionDetailRow = (i: number, row: Object) =>
    row.hasOwnProperty('detailRow')

在下面的 stackblitz 中,请注意这段代码,它本质上是获取原始元素并将其与名为 detailRow 的属性以及用于呈现展开行中的数据的元素的冗余副本连接起来。 (因为它们是分开的,不使用相同的数据对象)rows.push(element, { detailRow: true, element })

export class ExampleDataSource extends DataSource<any> {
  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<Element[]> {
    const rows = [];
    ELEMENT_DATA.forEach(element => rows.push(element, { detailRow: true, element }));
    console.log(rows);
    return of(rows);
  }

  disconnect() { }
}

堆栈闪电战

https://stackblitz.com/edit/div-on-click-qqcdmx?embed=1&file=app/table-basic-example.ts


NgOnInit 中的incidentArray.map() 期间,请确保将此属性添加到要展开的行中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    相关资源
    最近更新 更多