javascript - Creating nested dynamic components in angular - Stack Overflow

admin2025-04-22  0

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

Share Improve this question edited Jul 25, 2019 at 21:05 user007 asked Jul 25, 2019 at 18:20 user007user007 1992 silver badges15 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

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

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745305134a295492.html

最新回复(0)