角度材料表内的内容投影

jed*_*ion 11 angular-material angular

而不是将数据显示到表格的常规方式。我正在尝试创建我的自定义表组件并通过 .

像这样:

<table mat-table [dataSource]="dataSource">
	<!-- I want to Render the header and cell data here -->
	<ng-content></ng-content>
	
	<mat-header-row *matHeaderRowDef="headers; sticky: true"></mat-header-row>
	<mat-row *matRowDef="let row; columns: headers;"></mat-row>
</table>
Run Code Online (Sandbox Code Playgroud)

所以我可以像这样调用这个自定义组件:

<app-customized-table>
	<ng-container matColumnDef="id">
		<mat-header-cell *matHeaderCellDef> Id </mat-header-cell>
		<mat-cell *matCellDef="let element"> {{element.Id}} </mat-cell>
	</ng-container>
	...etc
</app-customized-table>
Run Code Online (Sandbox Code Playgroud)

但是,它不会检测内容。这是我正在尝试做的一个 stackblitz 示例。

https://stackblitz.com/edit/angular-qwvcln?file=src%2Fapp%2Fcustom-table.component.ts

有没有办法做到这一点?

谢谢。

yab*_*aba 27

聚会有点晚,但我遇到了同样的挑战,并能够按如下方式解决它:

您可以通过使用@ContentChildren@ViewChild功能以编程方式将列定义添加到表中来解决它

您的模板文件(例如customized-table.component.html):

<table mat-table [dataSource]="dataSource">
    <ng-content></ng-content>

    <mat-header-row *matHeaderRowDef="headers; sticky: true"></mat-header-row>
    <mat-row *matRowDef="let row; columns: headers;"></mat-row>
</table>
Run Code Online (Sandbox Code Playgroud)

您的代码隐藏(例如customized-table.component.ts):

@Component({
    selector: 'app-customized-table',
    templateUrl: './customized-table.component.html'
})
export class CustomizedTableComponent<T> implements AfterContentInit {
    constructor() { }

    @Input() dataSource: T[]; // or whatever type of datasource you have
    @Input() headers: string[];

    // this is where the magic happens: 
    @ViewChild(MatTable, { static: true }) table: MatTable<T>;
    @ContentChildren(MatColumnDef) columnDefs: QueryList<MatColumnDef>;

    // after the <ng-content> has been initialized, the column definitions are available.
    // All that's left is to add them to the table ourselves:
    ngAfterContentInit() {
        this.columnDefs.forEach(columnDef => this.table.addColumnDef(columnDef));
    }
}

Run Code Online (Sandbox Code Playgroud)

现在,您可以使用:

<app-customized-table [headers]="headers">
    <ng-container matColumnDef="id">
        <mat-header-cell *matHeaderCellDef> Id </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.Id}} </mat-cell>
    </ng-container>
    ...etc
</app-customized-table>
Run Code Online (Sandbox Code Playgroud)

使用延迟加载模块的 Stackblitz 工作演示


G. *_*ter 2

您必须采取一种非常不同的方法才能使其发挥作用。正如您所注意到的,mat-table 不能将其内容包装在其他内容中。一种可能性是仅向自定义组件提供数据,而不是 DOM 作为内容。例如:

成分:

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-custom-table',
  template: `
    <div>
      {{name}}

      <div class="example-container mat-elevation-z8">
        <table mat-table [dataSource]="dataSource">

          <mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
          <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>

          <ng-container *ngFor="let column of displayedColumns; index as i" >

            <ng-container [matColumnDef]="column">
              <mat-header-cell *matHeaderCellDef>{{ columnLabels[i] }}</mat-header-cell>
              <mat-cell mat-cell *matCellDef="let element"> {{element[valueKeys[i]]}} </mat-cell>
            </ng-container>

          </ng-container>

        </table>
      </div>

      asd
    </div>
  `
})
export class CustomTable implements OnInit {
  @Input() public columnLabels: any[];
  @Input() public displayedColumns;
  @Input() public dataSource;
  @Input() public name: any;
  @Input() public valueKeys: any[];

  constructor() { }

  ngOnInit() {
  }

}
Run Code Online (Sandbox Code Playgroud)

用法:

<app-custom-table name="sdf" 
    [dataSource]="dataSource" 
    [displayedColumns]="displayedColumns"
    [columnLabels]="columnLabels" 
    [valueKeys]="displayedColumns">

</app-custom-table>
Run Code Online (Sandbox Code Playgroud)

在哪里:

displayedColumns = ['position', 'name', 'weight', 'symbol'];
dataSource = ELEMENT_DATA;
columnLabels = ['No.', 'Name', 'Weight', 'Symbol'];
Run Code Online (Sandbox Code Playgroud)

但即便如此,也可能会遇到更多挑战。