I Want to know how to create nested dynamic ponents and maintains its parent child relationship.
For example, I have data like this,
- A
--A.1
--A.2
-B
--B.1
-C
I wanted to create the ponent like this,
<A>
<A1></A1>
<A2></A2>
</A>
<B>
<B1></B1>
</B>
<C></C>
But with my code I could only create parent ponent or child ponent. But not both.
Below is my code,
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
}
thisponentFactory = thisponentFactoryResolver.resolveComponentFactory(type);
thisponentReference = this.rootViewContainer.createComponent(thisponentFactory);
if (thisponentReference.instance.contentOnCreate) {
thisponentReference.instance.contentOnCreate(content);
}
}
With this code, I get this output.
Link to working example, StackBlitz
Please help me to resolve this issue.
Updated.
Even after adding the viewChild
, It still throws the viewchild not defined
.
Refer this image, In the ponent.instance I'm not seeing the view child element.
Updated stackblitz link /app/content/a/aponent.ts
I Want to know how to create nested dynamic ponents and maintains its parent child relationship.
For example, I have data like this,
- A
--A.1
--A.2
-B
--B.1
-C
I wanted to create the ponent like this,
<A>
<A1></A1>
<A2></A2>
</A>
<B>
<B1></B1>
</B>
<C></C>
But with my code I could only create parent ponent or child ponent. But not both.
Below is my code,
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.ponentFactory = this.ponentFactoryResolver.resolveComponentFactory(type);
this.ponentReference = this.rootViewContainer.createComponent(this.ponentFactory);
if (this.ponentReference.instance.contentOnCreate) {
this.ponentReference.instance.contentOnCreate(content);
}
}
With this code, I get this output.
Link to working example, StackBlitz
Please help me to resolve this issue.
Updated.
Even after adding the viewChild
, It still throws the viewchild not defined
.
Refer this image, In the ponent.instance I'm not seeing the view child element.
Updated stackblitz link https://stackblitz./edit/angular-dynamic-new-mepwch?file=src/app/content/a/a.ponent.ts
You should create ViewContainer on each level that is going to render child ponents:
a.ponent.html
<p>
a works!
</p>
<ng-container #container></ng-container>
a.ponent.ts
export class AComponent implements OnInit {
@ViewChild('container', { read: ViewContainerRef, static: true }) embeddedContainer: ViewContainerRef;
And then render ponent to dedicated container:
create-dynamic-ponent.service.ts
@Injectable()
export class CreateDynamicComponentService {
constructor(
private ponentFactoryResolver: ComponentFactoryResolver,
@Inject(CONTENT_MAPPINGS) private contentMappings: any,
private inlineService: InlineService
) { }
createComponent(content: any, type: any, vcRef) {
const ponentRef = this.renderComp(content, type, vcRef)
if (content.child && content.child.length) {
if (!ponentRef.instance.embeddedContainer) {
const cmpName = ponentRef.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, ponentRef.instance.embeddedContainer);
});
}
}
renderComp(content,type, vcRef: ViewContainerRef) {
const ponentFactory = this.ponentFactoryResolver.resolveComponentFactory(type);
const ponentRef = vcRef.createComponent<any>(ponentFactory);
if (ponentRef.instance.contentOnCreate) {
ponentRef.instance.contentOnCreate(content);
}
return ponentRef;
}
}
Note how renderComp
method takes ViewContainerRef
from the ponent with children:
this.createComponent(type, typeP, ponentRef.instance.embeddedContainer);
Forked Stackblitz