问题描述
这是我可以找到的唯一指南.
This is the sole guide I can find.
https://angular.io/guide/dynamic-component-loader
https://angular.io/guide/dynamic-component-loader
我使用的是相同的方法,所以一切都非常基础.直到有了递归组件.
I am using the same method so everything is quite basic. Until you have a recursive component.
让我们想象一下这种数据形状:
Let's imagine this shape of data:
{
component: {
id: "container",
components: [
{
id: "container",
components: [
{
id: "text",
data: "Hi"
}
]
}
]
}
}
这是什么意思:
-
Container
需要访问DynamicComponentLoader
-
DynamicComponentLoader
可以构造一个Container
- 请参阅第一步.
Container
requires access toDynamicComponentLoader
DynamicComponentLoader
can construct aContainer
- See the first step.
Angular警告我,存在循环依赖关系,这是正确的.
Angular warns me that there is a Circular Dependency and quite rightly so.
但是我在这个问题上花了一个星期,我绝对看不到解决方案.我认为我将不得不停止使用动态组件,而不得不返回使用@Input
.如ButtonContainer
和ImageContainer
等.我似乎无法制作一个通用容器.我被卡在平坦的表面上.
But I have spent a week on this issue and I definitely cannot see a solution. I think I am going to have to stop using dynamic components, and am forced to return to using @Input
. Like ButtonContainer
and ImageContainer
and so on. I can't seem to make a generic container. I am stuck on a flat surface.
那真是痛苦.有人有什么想法吗?
That is a real pain. Does anyone have any ideas?
推荐答案
我按照@OP的要求发布评论作为答案.
I post my comment as an answer as requested by @OP.
官方角度文档中有一个很好的例子有关如何创建动态组件的信息.基本上,它包含一个组件(AdBannerComponent
),可以使用 ComponentFactoryResolver 从给定列表创建组件.
There is a great example in the official angular documentation on how to create dynamic component. Basically it contains a component (AdBannerComponent
) that can create component from a given list using ComponentFactoryResolver.
基于此示例,我们可以创建一个仅重用AdBannerComponent
的新组件:
Based on this example we can create a new component that just reuse the 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
中的输入给定的组件.我们还可以通过更新其定义以匹配AdItem
来直接重用AdBannerComponent
:
This component will create dynamically the component given as an input in data
. We can also directly reuse AdBannerComponent
as is by updating it's definition to match 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
(提供要创建的组件列表):
If we update the AdService
(providing the list of component to create) with the following:
@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'})])
];
}
}
我们正在另一个内部创建动态组件,我们可以根据需要做得更深.
We are creating dynamic component inside another one and we can do it as deep as we want.
您可以在此处找到正在运行的示例 https://stackblitz.com/edit/angular-dsivwn .
You can find a running example here https://stackblitz.com/edit/angular-dsivwn.
这篇关于Angular是否支持递归嵌套动态组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!