这是我可以找到的唯一指南。
https://angular.io/guide/dynamic-component-loader
我使用的是相同的方法,所以一切都非常基础。直到有了递归组件。
让我们想象一下这种数据形状:
{
component: {
id: "container",
components: [
{
id: "container",
components: [
{
id: "text",
data: "Hi"
}
]
}
]
}
}
这是什么意思:
Container
需要访问DynamicComponentLoader
DynamicComponentLoader
可以构建Container
Angular警告我存在循环依赖,这是正确的。
但是我在这个问题上花了一个星期,我绝对看不到解决方案。我认为我将不得不停止使用动态组件,而不得不返回使用@Input
。像ButtonContainer
和ImageContainer
等。我似乎无法制作一个通用容器。我被卡在平坦的表面上。
那真是痛苦。有人有什么想法吗?
答案 0 :(得分:1)
我按照@OP的要求发表评论作为答案。
official angular documentation中有一个很好的示例,说明如何创建动态组件。基本上,它包含一个组件(AdBannerComponent
),可以使用ComponentFactoryResolver从给定列表中创建组件。
基于此示例,我们可以创建一个仅重用AdBannerComponent
的新组件:
import { Component, Input, ComponentFactoryResolver, ViewChild, OnInit } from '@angular/core';
import { AdComponent } from './ad.component';
import { AdItem } from './ad-item';
import { AdDirective } from './ad.directive';
@Component({
template: `
<div class="job-ad">
<app-ad-banner [ads]="ads"></app-ad-banner>
</div>
`})
export class HeroSubProfileComponent implements AdComponent, OnInit {
@Input() data: any;
ads: AdItem[];
constructor() { }
ngOnInit() {
this.ads = this.data;
}
}
此组件将动态创建在data
中作为输入给出的组件。我们还可以通过更新其定义以匹配AdBannerComponent
来直接重用AdItem
:
export class AdBannerComponent implements OnInit, OnDestroy {
@Input() ads: AdItem[];
currentAdIndex = -1;
@ViewChild(AdDirective) adHost: AdDirective;
interval: any;
@Input() data: any;
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
ngOnInit() {
if (this.data != null) {
this.ads = this.data;
}
this.loadComponent();
this.getAds();
}
如果我们使用以下内容更新AdService
(提供要创建的组件列表):
@Injectable()
export class AdService {
getAds() {
return [
new AdItem(HeroProfileComponent, {name: 'Bombasto', bio: 'Brave as they come'}),
new AdItem(HeroProfileComponent, {name: 'Dr IQ', bio: 'Smart as they come'}),
new AdItem(HeroJobAdComponent, {headline: 'Hiring for several positions',
body: 'Submit your resume today!'}),
new AdItem(HeroJobAdComponent, {headline: 'Openings in all departments',
body: 'Apply today'}),
// component using composition
new AdItem(HeroSubProfileComponent, [new AdItem(HeroProfileComponent, {name: 'Great Scott', bio: 'Awesome'})]),
// directly using AdBannerComponent
new AdItem(AdBannerComponent, [new AdItem(HeroProfileComponent, {name: 'Bombasto', bio: 'Brave as they come'})])
];
}
}
我们正在另一个内部创建动态组件,我们可以根据需要做得更深。
您可以在https://stackblitz.com/edit/angular-dsivwn上找到正在运行的示例。