网站搜索

typescript - 在 angular 中从 ngContent 传递数据


我想创建一个生成数据表格的子组件。所以,我创建了 grid.component.html 和 grid.component.ts。我的目标是,我的团队成员永远不去动 grid.ts 和 grid.html。因为我的表格结构在我应用的所有页面中都会类似。所以,他们只需要添加 myComponent.html 和 myComponent.ts。他们会在 myComponent 中编写按钮的 HTML 和按钮的点击事件。我可以创建表格。但我的问题是,我无法在 showDetail 方法中访问 rowData("rowData" 是 PrimeNg 指令的隐式属性,我没有在任何地方设置它。我只提供了 p-table 的 value。)

myComponent.html

<app-grid>
  <ng-template pTemplate="body" let-rowData="rawData">
        <button label="Reject" (click)="reject(rowData)"></button>
        <button label="Detail" (click)="showDetail(rowData)"></button>
  </ng-template>
</app-grid>

myComponent.ts

reject(data){
  console.log("Reject data ", data);
}

showDetail(data){
   console.log("showDetail data ", data);
}

grid.component.ts

rawData = {}

@ContentChild(TemplateRef)
templateRef : TemplateRef<any>;

grid.component.html

<p-table [value]="globalVariables.myData">
   <ng-template pTemplate="body" let-rowData>  // This rowData come from PrimeNg "implicit" value
     <tr>
       <td *ngFor="let col of globalVariables.columns">
          {{ rowData[col.field] }}
       </td>
       <td>
         <ng-template *ngTemplateOutlet="templateRef; context : {rawData : rawData}"></ng-template>
       </td>
     </tr>
   </ng-template>
</p-table>

答案#1

你正在寻找的是可以作为父组件 app-grid 部分的动态 HTML 模板。因此,你应该使用 <ng-template> 而不是 <ng-content>。

你的 app-grid 将会是

grid.component.html

<table>
    <tr>
      <td>
        <ng-template 
     *ngTemplateOutlet="templateRef; context : {rawData : rawData, reject : reject, showDetail : showDetail}"
     >
     </ng-template>
      </td>
    </tr>
</table>

grid.component.ts

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

@Component({
  selector: 'app-grid',
  templateUrl: './grid.component.html',
  styleUrls: ['./grid.component.css']
})
export class GridComponent implements OnInit {

  constructor() { }

  rawData = { content : " some content here"}

  @ContentChild(TemplateRef)
  templateRef : TemplateRef<any>;

  ngOnInit() {
  }

  reject(data){
    console.log("Reject data ", data);
  }

  showDetail(data){
     console.log("showDetail data ", data);
  }

}

使用组件网格

<app-grid>
  <ng-template let-rowData="rawData" let-reject="reject" let-showDetail="showDetail">
    <button label="Reject" (click)="reject(rowData)">Reject</button>
    <button label="Detail" (click)="showDetail(rowData)">Show Details</button>
  </ng-template>
</app-grid>

你可以在这里看到工作副本 - https://stackblitz.com/edit/angular-g15twn

答案#2

在子组件中使用 @Input

<ng-content [rowData] = 'rowData' ></ng-content>

myComponent.ts

@Input rowData: any;