Angular 2:要使用另一个组件的静态 <td> 和动态 <td> 渲染 table 的组件
Angular 2: Component to render table with static <td>s and dynamic <td>s from another component
我有一个 Angular 2 组件,它用小猫对象数据渲染了一个很好的 table。
由于 一些 的列将在不同的组件中重复使用,我正在寻找一种方法将 <td>
提取到一个单独的组件中( dynamic-kitten-tds
)。我无法移动呈现 kitten.name
和 kitten.lastWashed
的 <td>
s,因为它们对于 cat-o-base
组件是唯一的:
cat-o-base.component.html
<table>
<tbody>
<tr *ngFor="let kitten of kittenBasket">
<td>{{ kitten.name }}</td>
<dynamic-kitten-tds [value]="kitten"></dynamic-kitten-tds>
<td>{{ kitten.lastWashed | date }}</td>
</tr>
</tbody>
<table>
动态小猫-tds.component.html
dynamic-kitten-tds
组件的整个模板如下所示:
<td *ngFor="let preference of kitten.preferences">{{ preference | json }}</td>
限制 1
我可能不会像这样使用*ngFor
:
<td>{{ kitten.name }}</td>
<td *ngFor="let preference of kitten.preferences" [value]="preference"></td>
<td>{{ kitten.lastWashed | date }}</td>
此限制来自必须作为 dynamic-kitten-tds
组件的一部分实施的业务逻辑。
限制2
代码必须产生有效的 DOM 发射。
问题
如何实现?使用辅助组件很好。使用特殊的结构指令也可以。
P.S
我查看了其他一些 SO 问题(例如 ),但是没有找到完全匹配的问题定义。
如果使用辅助组件没问题,我的想法是:
动态-outlet.ts
@Directive({selector: '[dynamicOutlet]'})
export class DynamicOutlet implements OnChanges, OnDestroy {
@Input() dynamicOutlet: Type<any>;
@Input() dynamicOutletModel: any;
private componentRef: ComponentRef<any> = null;
constructor(private vcRef: ViewContainerRef) {}
ngOnChanges(changes: SimpleChanges) {
this.vcRef.clear();
this.componentRef = null;
if (this.dynamicOutlet) {
const elInjector = this.vcRef.parentInjector;
const componentFactoryResolver = elInjector.get(ComponentFactoryResolver);
const componentFactory = componentFactoryResolver.resolveComponentFactory(this.dynamicOutlet);
this.componentRef = componentFactory.create(elInjector);
this.componentRef.changeDetectorRef.detectChanges();
this.componentRef.instance.model = this.dynamicOutletModel;
this.vcRef.createEmbeddedView(this.componentRef.instance.template, { $implicit: this.dynamicOutletModel });
}
}
ngOnDestroy() {
if(this.componentRef) {
this.vcRef.clear();
this.vcRef = null;
}
}
}
kitten.ts
@Component({
selector: 'kitten-component',
template: `
<ng-template let-model>
<td *ngFor="let preference of model.preferences">{{ preference | json }}</td>
</ng-template>
`
})
export class Kitten {
@ViewChild(TemplateRef) template: TemplateRef<any>;
model: any;
}
然后你就可以像
一样使用它了
查看
<ng-container *dynamicOutlet="kittenComp; model: kitten"></ng-container>
分量
kittenComp = Kitten;
不要忘记将 Kitten
组件添加到 entryComponents
数组。
我有一个 Angular 2 组件,它用小猫对象数据渲染了一个很好的 table。
由于 一些 的列将在不同的组件中重复使用,我正在寻找一种方法将 <td>
提取到一个单独的组件中( dynamic-kitten-tds
)。我无法移动呈现 kitten.name
和 kitten.lastWashed
的 <td>
s,因为它们对于 cat-o-base
组件是唯一的:
cat-o-base.component.html
<table>
<tbody>
<tr *ngFor="let kitten of kittenBasket">
<td>{{ kitten.name }}</td>
<dynamic-kitten-tds [value]="kitten"></dynamic-kitten-tds>
<td>{{ kitten.lastWashed | date }}</td>
</tr>
</tbody>
<table>
动态小猫-tds.component.html
dynamic-kitten-tds
组件的整个模板如下所示:
<td *ngFor="let preference of kitten.preferences">{{ preference | json }}</td>
限制 1
我可能不会像这样使用*ngFor
:
<td>{{ kitten.name }}</td>
<td *ngFor="let preference of kitten.preferences" [value]="preference"></td>
<td>{{ kitten.lastWashed | date }}</td>
此限制来自必须作为 dynamic-kitten-tds
组件的一部分实施的业务逻辑。
限制2
代码必须产生有效的 DOM 发射。
问题
如何实现?使用辅助组件很好。使用特殊的结构指令也可以。
P.S
我查看了其他一些 SO 问题(例如
如果使用辅助组件没问题,我的想法是:
动态-outlet.ts
@Directive({selector: '[dynamicOutlet]'})
export class DynamicOutlet implements OnChanges, OnDestroy {
@Input() dynamicOutlet: Type<any>;
@Input() dynamicOutletModel: any;
private componentRef: ComponentRef<any> = null;
constructor(private vcRef: ViewContainerRef) {}
ngOnChanges(changes: SimpleChanges) {
this.vcRef.clear();
this.componentRef = null;
if (this.dynamicOutlet) {
const elInjector = this.vcRef.parentInjector;
const componentFactoryResolver = elInjector.get(ComponentFactoryResolver);
const componentFactory = componentFactoryResolver.resolveComponentFactory(this.dynamicOutlet);
this.componentRef = componentFactory.create(elInjector);
this.componentRef.changeDetectorRef.detectChanges();
this.componentRef.instance.model = this.dynamicOutletModel;
this.vcRef.createEmbeddedView(this.componentRef.instance.template, { $implicit: this.dynamicOutletModel });
}
}
ngOnDestroy() {
if(this.componentRef) {
this.vcRef.clear();
this.vcRef = null;
}
}
}
kitten.ts
@Component({
selector: 'kitten-component',
template: `
<ng-template let-model>
<td *ngFor="let preference of model.preferences">{{ preference | json }}</td>
</ng-template>
`
})
export class Kitten {
@ViewChild(TemplateRef) template: TemplateRef<any>;
model: any;
}
然后你就可以像
一样使用它了查看
<ng-container *dynamicOutlet="kittenComp; model: kitten"></ng-container>
分量
kittenComp = Kitten;
不要忘记将 Kitten
组件添加到 entryComponents
数组。