Angular 2+: 在另一个组件中使用组件作为输入
Angular 2+: Use component as input in another component
如何将组件用作 Angular 中另一个组件的输入数据?
例如:
我想要构建 table 组件 AppTableComponent:
<app-table [dataSource]="dataSource" [columns]="columns">
<ng-container tableColumnDef="actions">
<a routerLink="/model/edit/{{item.id}}" routerLinkActive="active">Edit</a>
<a routerLink="/model/delete/{{item.id}}" routerLinkActive="active">Delete</a>
</ng-container>
<ng-container tableColumnDef="isActive">
<div [ngClass]="{cercl:true, 'is-active':item.is_active}"> </div>
</ng-container>
</app-table>
dataSource
是类似于 Model[]
或 Person[]
或 Car[]
的数据数组总和。 columns
是一个类似于 ['id', 'isActive', 'name', 'actions']
的字符串数组。它应该包含数据源行属性名称或附加列名称。
我知道如何使用 ng-content
但这不是相同的情况。不同之处在于我应该在连续的地方使用部分内容。也许我应该使用ng-contet,但我不知道。
我确定我的目标是可行的,因为 Angular material table 是这样工作的:
<mat-table #table [dataSource]="dataSource">
<ng-container matColumnDef="position"></ng-container>
<ng-container matColumnDef="weight"></ng-container>
</mat-table>
请不要建议我使用 Angular material table 组件。我不需要 table。我只是想学点新东西。
如果有任何关于该主题的信息或文章,我将不胜感激!
如果您想在消费者部分管理模板,则必须使用 Angular 嵌入式视图 (ng-template
)。这就是 material 在其 table 实施中使用的内容。
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
你可以说没有任何嵌入式视图,但让我们看看上面模板的扩展版本:
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="position">
<ng-template matHeaderCellDef>
<th mat-header-cell> No. </th>
</ng-template>
<ng-template matCellDef let-element="$implicit">
<td mat-cell> {{element.position}} </td>
</ng-template>
</ng-container>
这里可以看到<ng-template matHeaderCellDef>
,可以用ContentChild
.
得到
Angular material 团队为此类模板创建专用指令 https://github.com/angular/material2/blob/f2c7205d6608d36a2016d90090be2a78d4f3233e/src/lib/table/cell.ts#L32 which keep references to embedded templates https://github.com/angular/material2/blob/676ce3b285718d2ee19ad6ae5702917566167641/src/cdk/table/cell.ts#L34
Material table 组件的模板如下:
<ng-container headerRowOutlet></ng-container>
<ng-container rowOutlet></ng-container>
<ng-container footerRowOutlet></ng-container>
还有指令助手,如:
@Directive({selector: '[headerRowOutlet]'})
export class HeaderRowOutlet implements RowOutlet {
constructor(public viewContainer: ViewContainerRef,
public elementRef: ElementRef) { }
}
以便我们可以使用低级别 api 创建基于嵌入式模板的元素,例如 ViewContainerRef.createEmbeddedView(templateRef)
但可以在此处找到简单的实现:
您可以使用@ContentChild('tableHeader') header: TemplateRef<any>;
您可以使用ContentChild
从内容DOM中获取第一个元素或匹配选择器的指令。
如果内容 DOM 发生变化,并且新的 child 匹配选择器,属性 将被更新。
您的 child component.html
读作
<ng-template [ngTemplateOutlet]="header"></ng-template>
<ng-template [ngTemplateOutlet]="body"></ng-template>
其中 [ngTemplateOutlet]
将读取 属性 值并将内容粘贴到指定模板中
最后,当您引用 parent 组件中的内容时,它将与上述模板一起放置
将内容从parent传递到child的方法
<compoent-selector>
<ng-template #tableHeader></ng-template>
<ng-template #body></ng-template>
</component-selector>
此 <ng-template>
中的任何内容都将放置在 child 组件中
在 child 组件中,您可以添加尽可能多的模板,所有模板都将与从 parent 组件传递的内容一起放置 - 这是从 [=] 传递内容的另一种方式44=] 到 child - 希望这会有所帮助 - 谢谢编码愉快!
点击here参考
如何将组件用作 Angular 中另一个组件的输入数据?
例如:
我想要构建 table 组件 AppTableComponent:
<app-table [dataSource]="dataSource" [columns]="columns">
<ng-container tableColumnDef="actions">
<a routerLink="/model/edit/{{item.id}}" routerLinkActive="active">Edit</a>
<a routerLink="/model/delete/{{item.id}}" routerLinkActive="active">Delete</a>
</ng-container>
<ng-container tableColumnDef="isActive">
<div [ngClass]="{cercl:true, 'is-active':item.is_active}"> </div>
</ng-container>
</app-table>
dataSource
是类似于 Model[]
或 Person[]
或 Car[]
的数据数组总和。 columns
是一个类似于 ['id', 'isActive', 'name', 'actions']
的字符串数组。它应该包含数据源行属性名称或附加列名称。
我知道如何使用 ng-content
但这不是相同的情况。不同之处在于我应该在连续的地方使用部分内容。也许我应该使用ng-contet,但我不知道。
我确定我的目标是可行的,因为 Angular material table 是这样工作的:
<mat-table #table [dataSource]="dataSource">
<ng-container matColumnDef="position"></ng-container>
<ng-container matColumnDef="weight"></ng-container>
</mat-table>
请不要建议我使用 Angular material table 组件。我不需要 table。我只是想学点新东西。
如果有任何关于该主题的信息或文章,我将不胜感激!
如果您想在消费者部分管理模板,则必须使用 Angular 嵌入式视图 (ng-template
)。这就是 material 在其 table 实施中使用的内容。
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
你可以说没有任何嵌入式视图,但让我们看看上面模板的扩展版本:
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="position">
<ng-template matHeaderCellDef>
<th mat-header-cell> No. </th>
</ng-template>
<ng-template matCellDef let-element="$implicit">
<td mat-cell> {{element.position}} </td>
</ng-template>
</ng-container>
这里可以看到<ng-template matHeaderCellDef>
,可以用ContentChild
.
Angular material 团队为此类模板创建专用指令 https://github.com/angular/material2/blob/f2c7205d6608d36a2016d90090be2a78d4f3233e/src/lib/table/cell.ts#L32 which keep references to embedded templates https://github.com/angular/material2/blob/676ce3b285718d2ee19ad6ae5702917566167641/src/cdk/table/cell.ts#L34
Material table 组件的模板如下:
<ng-container headerRowOutlet></ng-container>
<ng-container rowOutlet></ng-container>
<ng-container footerRowOutlet></ng-container>
还有指令助手,如:
@Directive({selector: '[headerRowOutlet]'})
export class HeaderRowOutlet implements RowOutlet {
constructor(public viewContainer: ViewContainerRef,
public elementRef: ElementRef) { }
}
以便我们可以使用低级别 api 创建基于嵌入式模板的元素,例如 ViewContainerRef.createEmbeddedView(templateRef)
但可以在此处找到简单的实现:
您可以使用@ContentChild('tableHeader') header: TemplateRef<any>;
您可以使用ContentChild
从内容DOM中获取第一个元素或匹配选择器的指令。
如果内容 DOM 发生变化,并且新的 child 匹配选择器,属性 将被更新。
您的 child component.html
读作
<ng-template [ngTemplateOutlet]="header"></ng-template>
<ng-template [ngTemplateOutlet]="body"></ng-template>
其中 [ngTemplateOutlet]
将读取 属性 值并将内容粘贴到指定模板中
最后,当您引用 parent 组件中的内容时,它将与上述模板一起放置
将内容从parent传递到child的方法
<compoent-selector>
<ng-template #tableHeader></ng-template>
<ng-template #body></ng-template>
</component-selector>
此 <ng-template>
中的任何内容都将放置在 child 组件中
在 child 组件中,您可以添加尽可能多的模板,所有模板都将与从 parent 组件传递的内容一起放置 - 这是从 [=] 传递内容的另一种方式44=] 到 child - 希望这会有所帮助 - 谢谢编码愉快!
点击here参考