Angular 使用ng内容转换创建动态中继器
我试图实现的是一个通用组件,它绑定到任意对象数组,当使用它的主组件也使用组件任意定义每行的视图时,它允许动态添加和删除行 请注意,Angular 使用ng内容转换创建动态中继器,angular,angular2-ngcontent,Angular,Angular2 Ngcontent,我试图实现的是一个通用组件,它绑定到任意对象数组,当使用它的主组件也使用组件任意定义每行的视图时,它允许动态添加和删除行 请注意,MasterComponent是一个可以为不同页面实现的任意组件,它是自包含的,不由任何元数据或外部源定义 到目前为止,我拥有以下组件: 重复组件模板: <input type="button" value="Add" (click)="addRow()"> <div class="repeater" *ngFor="let row of repea
MasterComponent
是一个可以为不同页面实现的任意组件,它是自包含的,不由任何元数据或外部源定义
到目前为止,我拥有以下组件:
重复组件模板:
<input type="button" value="Add" (click)="addRow()">
<div class="repeater" *ngFor="let row of repeaterArray">
<div class="repeaterRow">
<input type="button" value="Remove" (click)="removeRow(row.rowId)">
<ng-content select="row"></ng-content>
</div>
</div>
<repeater [repeaterArray]="repeaterObj">
<row>
<field-textbox [data]="row.name" [label]="'Name'"></field-textbox>
<field-textbox [data]="row.description" [label]="'Description'"></field-textbox>
</row>
</repeater>
这种方法有两个问题,我似乎找不到解决方案
ngFor
复制模板时,所有行的ng content
选择器都是相同的,在渲染后只剩下一个ng content
转换点
transcluded指令中,ngFor
声明中没有对行
变量的引用,因此无法正确绑定数据RepeaterComponent
,让我尽可能少地创建更多不同任意结构和不同模板的新MasterComponents
以下是实现动态中继器的步骤:
第一步是提供TemplateRef
作为RepeaterComponent
的子元素:
<repeater [repeaterArray]="repeaterObj">
<ng-template>
...
</ng-template>
</repeater>
第三步是使用ngTemplateOutlet
呈现模板:
@Component({
selector: 'repeater',
template: `
<input type="button" value="Add" (click)="addRow()">
<div class="repeater" *ngFor="let row of repeaterArray">
<div class="repeaterRow">
<input type="button" value="Remove" (click)="removeRow(row.rowId)">
<ng-template <== this line
[ngTemplateOutlet]="itemTemplate"
[ngTemplateOutletContext]="{ $implicit: row }">
</ng-template>
</div>
</div>`
})
export class RepeaterComponent {
@Input() repeaterArray: Array<any>;
@ContentChild(TemplateRef) itemTemplate: TemplateRef<any>;
...
}
注意:我们正在传递带有$implicit
属性的ngOutletContext
like对象
在上下文对象中使用$implicit键将其值设置为
默认
其工作原理如下:
[ngTemplateOutletContext]="{ $implicit: row }" ==> <template let-row>
[ngTemplateOutletContext]="{ item: row }" ==> <template let-row="item">
[ngTemplateOutletContext]=“{$implicit:row}”==>
[ngTemplateOutletContext]=“{item:row}”==>
ngOutletContext
仅在2.0.0-rc.2的Angular 2版本之后可用
您可以尝试相应的(更新为5.0.0)看起来这正是我想要的,谢谢!唯一一件似乎没有按预期工作的事情是使用[(ngModel)]对字段textbox组件进行双向绑定。下面演示了在尝试使用相同绑定更改两个不同的输入字段时出现的问题。在应用程序组件模板中,您可以看到正常的
绑定按预期工作,并更新对象绑定,但更改文本框不会将绑定应用回对象。请尝试使用EventEmitter
实现双向绑定,就像Yep一样,这是可行的。我希望绑定能够正确传播,而不必在组件上实现双向绑定,尽管在使用[ngTemplateOutlet]的模板之外使用绑定时也可以正常工作。这与不使用ngTemplateOutlet的行为相同。ngTemplateOutlet并不是一个魔术。它只是在TemplateRefAh中传递数据,你是对的。我在考虑绑定到已定义的类实例,而不是绑定到JSON属性。再次感谢!
@Component({
selector: 'repeater',
template: `
<input type="button" value="Add" (click)="addRow()">
<div class="repeater" *ngFor="let row of repeaterArray">
<div class="repeaterRow">
<input type="button" value="Remove" (click)="removeRow(row.rowId)">
<ng-template <== this line
[ngTemplateOutlet]="itemTemplate"
[ngTemplateOutletContext]="{ $implicit: row }">
</ng-template>
</div>
</div>`
})
export class RepeaterComponent {
@Input() repeaterArray: Array<any>;
@ContentChild(TemplateRef) itemTemplate: TemplateRef<any>;
...
}
<repeater [repeaterArray]="repeaterObj">
<template let-row>
<field-textbox [data]="row.name" [label]="'Name'"></field-textbox>
<field-textbox [data]="row.description" [label]="'Description'"></field-textbox>
</template>
</repeater>
[ngTemplateOutletContext]="{ $implicit: row }" ==> <template let-row>
[ngTemplateOutletContext]="{ item: row }" ==> <template let-row="item">