在 angular 中创建嵌套动态组件
Creating nested dynamic components in angular
我想知道如何创建嵌套的动态组件并维护其父子关系。
比如我有这样的数据,
- A
--A.1
--A.2
-B
--B.1
-C
我想创建这样的组件,
<A>
<A1></A1>
<A2></A2>
</A>
<B>
<B1></B1>
</B>
<C></C>
但是我的代码只能创建父组件或子组件。但不是两者。
下面是我的代码,
setRootViewContainerRef(view: ViewContainerRef): void {
this.rootViewContainer = view;
}
createComponent(content: any, type: any) {
console.log(content);
if (content.child && content.child.length > 0) {
content.child.forEach(type => {
const typeP = this.contentMappings[type.type];
this.createComponent(type, typeP);
});
} else {
this.renderComp(content,type)
}
}
renderComp(content,type) {
if (!type) {
return
}
this.componentFactory = this.componentFactoryResolver.resolveComponentFactory(type);
this.componentReference = this.rootViewContainer.createComponent(this.componentFactory);
if (this.componentReference.instance.contentOnCreate) {
this.componentReference.instance.contentOnCreate(content);
}
}
使用这段代码,我得到了这个输出。
Link 工作示例,StackBlitz
请帮我解决这个问题。
已更新。
即使添加了 viewChild
,它仍然会抛出 viewchild not defined
。
参考这张图片,在 component.instance 我没有看到视图子元素。
已更新 stackblitz link https://stackblitz.com/edit/angular-dynamic-new-mepwch?file=src/app/content/a/a.component.ts
您应该在要呈现子组件的每个级别上创建 ViewContainer:
a.component.html
<p>
a works!
</p>
<ng-container #container></ng-container>
a.component.ts
export class AComponent implements OnInit {
@ViewChild('container', { read: ViewContainerRef, static: true }) embeddedContainer: ViewContainerRef;
然后将组件渲染到专用容器:
创建动态-component.service.ts
@Injectable()
export class CreateDynamicComponentService {
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
@Inject(CONTENT_MAPPINGS) private contentMappings: any,
private inlineService: InlineService
) { }
createComponent(content: any, type: any, vcRef) {
const componentRef = this.renderComp(content, type, vcRef)
if (content.child && content.child.length) {
if (!componentRef.instance.embeddedContainer) {
const cmpName = componentRef.instance.constructor.name;
throw new TypeError(`Trying to render embedded content. ${cmpName} must have @ViewChild() embeddedContainer defined`);
}
content.child.forEach(type => {
const typeP = this.contentMappings[type.type];
this.createComponent(type, typeP, componentRef.instance.embeddedContainer);
});
}
}
renderComp(content,type, vcRef: ViewContainerRef) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(type);
const componentRef = vcRef.createComponent<any>(componentFactory);
if (componentRef.instance.contentOnCreate) {
componentRef.instance.contentOnCreate(content);
}
return componentRef;
}
}
请注意 renderComp
方法如何从具有子组件的组件中获取 ViewContainerRef
:
this.createComponent(type, typeP, componentRef.instance.embeddedContainer);
我想知道如何创建嵌套的动态组件并维护其父子关系。
比如我有这样的数据,
- A
--A.1
--A.2
-B
--B.1
-C
我想创建这样的组件,
<A>
<A1></A1>
<A2></A2>
</A>
<B>
<B1></B1>
</B>
<C></C>
但是我的代码只能创建父组件或子组件。但不是两者。
下面是我的代码,
setRootViewContainerRef(view: ViewContainerRef): void {
this.rootViewContainer = view;
}
createComponent(content: any, type: any) {
console.log(content);
if (content.child && content.child.length > 0) {
content.child.forEach(type => {
const typeP = this.contentMappings[type.type];
this.createComponent(type, typeP);
});
} else {
this.renderComp(content,type)
}
}
renderComp(content,type) {
if (!type) {
return
}
this.componentFactory = this.componentFactoryResolver.resolveComponentFactory(type);
this.componentReference = this.rootViewContainer.createComponent(this.componentFactory);
if (this.componentReference.instance.contentOnCreate) {
this.componentReference.instance.contentOnCreate(content);
}
}
使用这段代码,我得到了这个输出。
Link 工作示例,StackBlitz
请帮我解决这个问题。
已更新。
即使添加了 viewChild
,它仍然会抛出 viewchild not defined
。
参考这张图片,在 component.instance 我没有看到视图子元素。
已更新 stackblitz link https://stackblitz.com/edit/angular-dynamic-new-mepwch?file=src/app/content/a/a.component.ts
您应该在要呈现子组件的每个级别上创建 ViewContainer:
a.component.html
<p>
a works!
</p>
<ng-container #container></ng-container>
a.component.ts
export class AComponent implements OnInit {
@ViewChild('container', { read: ViewContainerRef, static: true }) embeddedContainer: ViewContainerRef;
然后将组件渲染到专用容器:
创建动态-component.service.ts
@Injectable()
export class CreateDynamicComponentService {
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
@Inject(CONTENT_MAPPINGS) private contentMappings: any,
private inlineService: InlineService
) { }
createComponent(content: any, type: any, vcRef) {
const componentRef = this.renderComp(content, type, vcRef)
if (content.child && content.child.length) {
if (!componentRef.instance.embeddedContainer) {
const cmpName = componentRef.instance.constructor.name;
throw new TypeError(`Trying to render embedded content. ${cmpName} must have @ViewChild() embeddedContainer defined`);
}
content.child.forEach(type => {
const typeP = this.contentMappings[type.type];
this.createComponent(type, typeP, componentRef.instance.embeddedContainer);
});
}
}
renderComp(content,type, vcRef: ViewContainerRef) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(type);
const componentRef = vcRef.createComponent<any>(componentFactory);
if (componentRef.instance.contentOnCreate) {
componentRef.instance.contentOnCreate(content);
}
return componentRef;
}
}
请注意 renderComp
方法如何从具有子组件的组件中获取 ViewContainerRef
:
this.createComponent(type, typeP, componentRef.instance.embeddedContainer);