4

我正在構建一個數據表組件,它被設計爲非常通用的組件。角度4:帶插值的動態模板

的思想是定義表作爲這樣的:

<app-datatable [items]="currentPageResult"> 
    <app-datatable-column attribute="id" 
          header="ID"></app-datatable-column> 
    <app-datatable-column attribute="name" 
          header="First Name"></app-datatable-column> 
    <app-datatable-column attribute="last_name" 
          header="Last Name"></app-datatable-column> 
</app-datatable> 

以這種方式,我們可以指定陣列插入DataTable部件,以及通過定義數據表柱我們可以決定女巫屬性應該顯示錶。在內部,表格將按列和另一個ngFor按項目執行ngFor。

這部分很簡單,現在它工作得很好,當我想要自定義HTML內容到td時,事情變得棘手;事情是這樣的:

<app-datatable [items]="currentPageResult"> 
    <app-datatable-column attribute="id" 
          header="ID" 
          [template]="titleTemplate"> 
     <ng-template #titleTemplate> 
      <a role="button" [routerLink]="[data.id]"> 
       {{data.id}} 
      </a> 
     </ng-template> 
    </app-datatable-column> 
    <app-datatable-column attribute="name" 
          header="First Name"></app-datatable-column> 
    <app-datatable-column attribute="last_name" 
          header="Last Name"></app-datatable-column> 
</app-datatable> 

注意到,我使用data作爲迭代變量,但它實際上是不行的,我只是說明了我想做的事情。

爲了解決這個問題,我使用'$ data'作爲簡單的字符串和自定義指令來將'$ data'替換爲相應的列/行值。

在我使用的是appDatatableContent指令,每個tbody td passig的row數據和colum設置的數據表組件(該指令只適用,如果科拉姆設置有一個模板):

<table class="table"> 
    <thead> 
    <tr> 
     <th *ngFor="let col of columns" [ngClass]="getColumnHeaderClasses(col)" (click)="onReorder(col)">{{col.header}}</th> 
    </tr> 
    </thead> 
    <tbody> 
    <tr *ngFor="let row of items.Items"> 
     <td *ngFor="let col of columns" appDatatableContent [column]="col" [row]="row"> 
     <ng-container *ngIf="!col.template; else col.template"> 
      {{row[col.attribute]}} 
     </ng-container> 
     </td> 
    </tr> 
    </tbody> 
</table> 

而且該指令基本上看起來爲包含「$數據」內,並替換「$ SDATA」的相應的列的值作爲這個的一種元素:

ngAfterViewInit() { 
    if (!this.column.template) { 
    return; 
    } 
    const element: HTMLElement = this.element.nativeElement; 
    const value = this.row[this.column.attribute]; 

    const children = element.getElementsByTagName('*'); 
    const length = children.length; 

    for (let i = 0; i < length; i++) { 
    const currentNode = children[i]; 
    if (!currentNode.children || !currentNode.children.length) { 
     const originalHTML: string = currentNode.innerHTML; 
     const fixedHTML = originalHTML.replace('$data', value); 
     currentNode.innerHTML = fixedHTML; 
    } 
    } 
} 

另外,注意每個小區有<ng-container *ngIf="!col.template; else col.template">,所以如果有任何模板綁定,單元格內容將呈現該模板,但問題是如何將參數(特別是行對象)傳遞給模板,以便模板可以使用該參數進行插值。

見工作plunker:https://plnkr.co/edit/84jhiquT5q3OQaCxTa5i

不過,這並不似乎是最好的方法,因爲我無法獲得的優勢,大量鄰角功率的,因爲我只是替換字符串值。

因此,我如何定義一個可以使用迭代變量呈現自定義單元格內容的動態模板?

回答

8

您可以輕鬆地通過使用內置指令NgTemplateOutlet,它允許你通過上下文EmbeddedViewng-template

解決您的問題

首先拆下DatatableContentDirective

然後在

數據 - 更改標記table.component。HTML

<td *ngFor="let col of columns"> 
    <ng-container *ngIf="!col.template; else customTemplate"> 
    {{row[col.attribute]}} 
    </ng-container> 
    <ng-template #customTemplate 
    [ngTemplateOutlet]="col.template" 
    [ngTemplateOutletContext]="{ col: col, row: row }"> 
    </ng-template> 
</td> 

和父組件使用

<ng-template #titleTemplate let-col="col" let-row="row"> 
    <a role="button" ...> 
     <b>Custom</b> {{row[col.attribute]}} 
    </a> 
</ng-template> 

Plunker Example

看到有關模板變量也更多信息let-name

+0

這就是我正在尋找的!!!!! :D 非常感謝。 –

+0

不客氣!很高興聽到它幫助:) – yurzui

+0

非常明確的答案 –