Angular 角度材质表内的内容投影

Angular 角度材质表内的内容投影,angular,angular-material,Angular,Angular Material,而不是将数据显示到表中的常规方式。我正在尝试创建自定义表组件,并通过在材质表中投影数据 像这样: <ng-container *ngFor=”let column of displayedColumns” matColumnDef=”{{column.id}}”> <th mat-header-cell *matHeaderCellDef mat-sort-header>{{column.name}}</th> <td mat-cell *m

而不是将数据显示到表中的常规方式。我正在尝试创建自定义表组件,并通过在材质表中投影数据

像这样:

<ng-container *ngFor=”let column of displayedColumns” matColumnDef=”{{column.id}}”>
   <th mat-header-cell *matHeaderCellDef mat-sort-header>{{column.name}}</th>
   <td mat-cell *matCellDef=”let row”>
      {{row[column.id]}}
   </td>
</ng-container>

您必须采取一种完全不同的方法来实现这一点。正如您所注意到的,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() {
  }

}
但即使这样,也可能会有更多的挑战。

派对迟到了一点,但我也遇到了同样的挑战,并且能够按如下方式解决它:

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

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


您的代码隐藏(例如,
自定义表.component.ts
):

@组件({
选择器:“应用程序自定义表”,
templateUrl:“./customized table.component.html”
})
导出类CustomizedTableComponent在ContentInit之后实现{
构造函数(){}
@Input()数据源:T[];//或任何类型的数据源
@Input()头:字符串[];
//这就是神奇发生的地方:
@ViewChild(MatTable,{static:true})table:MatTable;
@ContentChildren(MatColumnDef)columnDefs:QueryList;
//初始化后,列定义可用。
//剩下的就是我们自己将它们添加到表中:
ngAfterContentInit(){
this.columnDefs.forEach(columnDef=>this.table.addColumnDef(columnDef));
}
}
现在,您可以使用:


您可以像这样投影内容:

<ng-container *ngFor=”let column of displayedColumns” matColumnDef=”{{column.id}}”>
   <th mat-header-cell *matHeaderCellDef mat-sort-header>{{column.name}}</th>
   <td mat-cell *matCellDef=”let row”>
      {{row[column.id]}}
   </td>
</ng-container>

{{column.name}
{{row[column.id]}
然后传递用于内容投影的模板:

<my-component …
[itemTemplate]=”itemTemplate”>
   <ng-template let-item #itemTemplate>
      column id: {{item.column.id}}
      value: {{item.value}}
   </ng-template>
</my-component>

列id:{{item.column.id}
值:{{item.value}}

谢谢。这是一个很好的例子,但你是对的,挑战将随之而来,其中之一是很难定制每个单元的数据。嗯,这实际上是我的第一个目标。我试过这个,但不起作用,你是怎么做到的?我的情况是在lazyloading模块中加载表,错误告诉我它是找不到id列。真的需要解决这个问题,否则代码必须重复编写,这是不可维护的,因为我的应用程序需要大量的表。您是否将
CustomizedTableComponent
放在a中,并将该模块导入延迟加载的模块中?@Stefan添加了一个stackblitz示例。。对于
displayedColumns
使用
columnDefs
的解决方案取消了独立于列定义选择要显示哪些列以及以何种顺序显示的选项。确保MatTableModule以某种方式导入到使用自定义表组件的模块中(请参见stackblitz示例),确保可以!只需添加
@ViewChild(MatSort,{static:true})sort:MatSort”,并确保您希望能够对其进行排序的标题单元格上具有
mat sort header
属性。然后使用
this.sort
来实现排序逻辑。@leitechera您的表是否在条件容器中(例如,使用
*ngIf
)?如果是,则使用
static:false
。更好的是,下载stackblitz项目并从那里开始工作。
<my-component …
[itemTemplate]=”itemTemplate”>
   <ng-template let-item #itemTemplate>
      column id: {{item.column.id}}
      value: {{item.value}}
   </ng-template>
</my-component>