这是我的组件:
import { Component, OnInit, ContentChildren, QueryList } from '@angular/core';
import { IconBoxComponent } from '../icon-box/icon-box.component';
@Component({
selector: 'app-three-icon-box',
templateUrl: './three-icon-box.component.html',
styleUrls: ['./three-icon-box.component.scss']
})
export class ThreeIconBoxComponent implements OnInit {
@ContentChildren(IconBoxComponent) boxes: QueryList<IconBoxComponent>;
constructor() { }
ngOnInit() {
}
ngAfterContentInit() {
console.log(this.boxes);
}
}
它的模板看起来像这样:
<div class="row justify-content-center">
<div class="col-12 col-md-10">
<div class="row justify-content-center text-center">
<div *ngFor="let box of boxes" class="col-12 col-sm-4 col-lg-3 offset-lg-1 lz-mb-2 lz-mb-sm-0">
{{ box }}
</div>
</div>
</div>
</div>
这就是我渲染它的方式:
<app-three-icon-box>
<app-icon-box icon="#icon-one">content 1</app-icon-box>
<app-icon-box icon="#icon-two">content 2</app-icon-box>
<app-icon-box icon="#icon-three">content 3</app-icon-box>
</app-three-icon-box>
在第二个代码块中,我试图渲染
<app-icon-box>
,但我不知道如何渲染。 {{ box }}
只是我想做的事情的一个想法,但我只是得到了[object Object]
。
你应该使用这个模式
@ContentChildren
注入标记。提示:您可以多次渲染每个模板并向它们发送参数。
示例:
import { Component, Input, Directive, TemplateRef, ContentChildren, QueryList } from '@angular/core';
@Directive({
selector: '[templateMarker]'
})
export class TemplateMarker {
constructor(public template: TemplateRef<any>) {}
}
@Component({
selector: 'template-owner',
template: `
<div *ngFor="let marker of markers">
<i><ng-template [ngTemplateOutlet]="marker.template"></ng-template></i>
</div>
`,
})
export class TemplateOwner {
@ContentChildren(TemplateMarker) markers: QueryList<TemplateMarker>;
}
@Component({
selector: 'hello',
template: `<template-owner>
<div *templateMarker>first template</div>
<div *templateMarker>second template</div>
</template-owner>`,
})
export class HelloComponent {}
有点不清楚你需要什么。 但我想使用 ng-content 就足够了。删除 ContentChildren 和 ngFor 并使用
<ng-content></ng-content>
在您的模板中。
然后您必须直接在声明盒子组件的位置添加类。
<app-icon-box class="col-12 col-sm-4 col-lg-3 offset-lg-1 lz-mb-2 lz-mb-sm-0" icon="#here-to-help-you">
为了丰富 ThreeIconBoxComponent 中的投影组件,您将需要使用模板和模板出口的完全不同的方法。
这是一个老问题,但我只是在我正在开发的应用程序中问同样的问题。
我不确定我的解决方案有多“正确”,但这就是我解决这个问题的方法。
就我而言,我的父母
component
只应该接受特定类型的内容(在您的情况下,这将是IconBoxComponent
)。
在该子项
component
(此处为IconBoxComponent
)中,我暴露了一个TemplateRef
,然后父级component
可以使用它进行渲染。
虽然使用
directive
也有效,但我不喜欢必须使用我的自定义子 component
以及自定义 directive
的想法。
注意:在下面的示例中,我删除了所有
CSS
classes
和一些 HTML
元素,以使其更具可读性。由于某些技术原因,它们没有被删除。
@Component({
selector: 'app-icon-box',
template: `
<ng-template #template>
<span>My Icon Box</span>
</ng-template>
`,
styleUrls: ['./icon-box.component.scss']
})
export class IconBoxComponent {
@ViewChild('template', { static: true }) template!: TemplateRef<any>;
}
@Component({
selector: 'app-three-icon-box',
template: `
<div>
<div *ngFor="let box of boxes">
<ng-container
[ngTemplateOutlet]="box.template"
></ng-container>
</div>
</div>
`,
styleUrls: ['./three-icon-box.component.scss']
})
export class ThreeIconBoxComponent {
@ContentChildren(IconBoxComponent) boxes = new QueryList<IconBoxComponent>();
}
<app-three-icon-box>
<app-icon-box>content 1</app-icon-box>
<app-icon-box>content 2</app-icon-box>
<app-icon-box>content 3</app-icon-box>
</app-three-icon-box>