fra*_*jay 9 javascript angular
我正在创建一个数据表模块,我的目标是特定的实现。我希望能够导入模块,并像这样使用它的组件:
randomcomponent.component.html
<datatable [data]="tableData">
<datatable-column>
<ng-template let-row="row">
<label> {{ row.value }} </label>
</ng-template>
</datatable-column>
</datatable>
Run Code Online (Sandbox Code Playgroud)
以下是数据表模块中的组件:
datatable.component.html (<datatable>)
<table class="datatable">
<thead>
<tr>
<th *ngFor="let header of tableData?.headers">
{{ header?.title }}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tableData?.data">
<ng-container *ngTemplateOutlet="template; context: { row: row }"></ng-container>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
Run Code Online (Sandbox Code Playgroud)
column.component.html (<datatable-column>)
<ng-template let-row="row">
<ng-container *ngTemplateOutlet="template; context: { row: row }"></ng-container>
</ng-template>
Run Code Online (Sandbox Code Playgroud)
虽然数据没有呈现。我使用了以前的方法,ng-content
但无法遍历内容。仅显示 1 个。我怎样才能最终得到我正在寻找的实现?我应该寻求不同的方法吗?
更新:提供的是我的 StackBlitz https://stackblitz.com/edit/angular-4esuor
这里的关键是,您需要找到外部模板内的嵌套模板,然后迭代这些外部模板。
您可以在这里寻求另一个指令的帮助(推荐但不是强制性的,请参见下面的注释),我们将其称为datatable-cell
指令,它非常简单,声明并导出它:
@Directive({
selector: '[datatable-cell]'
})
export class DatatableCellDirective {
constructor(public templateRef: TemplateRef<any>) { }
}
Run Code Online (Sandbox Code Playgroud)
仅公开模板引用,不执行任何其他操作。
接下来,如果使用该指令,则将其添加到模板的所有列中(let-row
如果使用上下文,则只需声明...或者如果需要显式上下文,则$implicit
坚持使用):let-row="row"
<datatable-column>
<ng-template datatable-cell let-row>
<label> {{ row.value }} </label>
</ng-template>
</datatable-column>
Run Code Online (Sandbox Code Playgroud)
在您的列组件中,使用该指令来查找并公开单元格模板ContentChild
:
@ContentChild(DatatableCellDirective)
cell: DatatableCellDirective
Run Code Online (Sandbox Code Playgroud)
笔记:您可以在没有DatatableCellDirective
, 的情况下执行此操作,只需@ContentChild(TemplateRef) cell: TemplateRef<any>
在列中设置,但这有点不太灵活,我建议使用该指令(如下所述)。
在表格组件中,找到ContentChildren
有很多列,并获取它们的单元格模板:
@ContentChildren(DatatableColumnComponent)
columns: QueryList<DatatableColumnComponent>;
cellTemplates: TemplateRef<any>[] = []
// content children available in this hook
ngAfterContentInit() {
this.cellTemplates = this.columns.toArray().map(c => c.cell.templateRef);
// like this if not using the cell directive and using TemplateRef directly
// this.cellTemplates = this.columns.toArray().map(c => c.cell);
}
Run Code Online (Sandbox Code Playgroud)
然后,在表 html 中,迭代数据行和单元格模板,因为您需要为每行中的每一列呈现一个单元格,将上下文设置到$implicit
此处,但使用任何合适的上下文(例如{row: row}
代替显式上下文):
<tr *ngFor="let row of tableData?.data">
<ng-container *ngFor="let tpl of cellTemplates">
<ng-container *ngTemplateOutlet="tpl; context: {$implicit: row}"></ng-container>
</ng-container>
</tr>
Run Code Online (Sandbox Code Playgroud)
你也可以把<td></td>
标签放入列迭代内,以具有强制列宽的实际表格单元格。
这是一个相当灵活的系统...您可以设想对其进行扩展,以便您可以在列中提供自定义列标题以及datatable-header
方便的指令,并且您可以在列和表格组件中找到这些模板,类似于查找单元格的方式,以便迭代并显示标题行中的内容。使用该指令还允许您使用除ng-template
使用该指令还允许您使用构建模板(如td
,并且可能允许您通过输入向单元格添加更多上下文。
闪电战: https ://stackblitz.com/edit/angular-gj5ean
小编辑,意识到ContentChildren
是可迭代的,因此您实际上可以跳过ngAfterContentInit
表组件中的部分,执行以下操作:
@ContentChildren(DatatableColumnComponent)
columns: QueryList<DatatableColumnComponent>;
Run Code Online (Sandbox Code Playgroud)
只需在模板中执行此操作...
<ng-container *ngFor="let col of columns">
<ng-container *ngTemplateOutlet="col.cell.templateRef; context: {$implicit: row}"></ng-container>
</ng-container>
Run Code Online (Sandbox Code Playgroud)
如果列本身发生变化(例如添加/删除列),它可以提供更好的变化检测
归档时间: |
|
查看次数: |
1071 次 |
最近记录: |