加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

角度4:带插值的动态模板

发布时间:2020-12-17 10:25:44 所属栏目:安全 来源:网络整理
导读:我正在构建一个数据表组件,它被设计为非常通用的组件. 我们的想法是将表定义为: app-datatable [items]="currentPageResult" app-datatable-column attribute="id" header="ID"/app-datatable-column app-datatable-column attribute="name" header="First
我正在构建一个数据表组件,它被设计为非常通用的组件.

我们的想法是将表定义为:

<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>

通过这种方式,我们可以将数组指定到数据表组件中,通过定义数据表列,我们可以决定应该显示表格.在内部,表将按列和另一个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’替换为相应的列/行值.

在datatable组件中,我在每个tbody td上使用appDatatableContent指令行数据和colum设置(该指令仅在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>

该指令基本上查找内部包含’$data’的元素,并替换相应列值的’$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

但它似乎并不是最好的方法,因为我只能替换字符串值,因此无法获得很多角度功率.

那么,?如何定义一个可以使用迭代变量来呈现自定义单元格内容的动态模板?

您可以使用内置指令NgTemplateOutlet轻松解决您的问题,该指令允许您将上下文传递给EmbeddedView(ng-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的更多信息

> What is $implicit in angular 2?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读