Scott
Scott

Reputation: 705

Iterate over ng-content items and wrap each in it's own nested div

I've read this isn't supported yet, but I was wondering if anyone has figured out a hacky workaround for this issue.

What I currently have is a parent component that has this template:

<dxi-item location='after' class="osii-item-content">
    <span><ng-content select="[osii-page-button]"></ng-content></span>
</dxi-item>

Which is creating the following:

<dxi-item location='after' class="osii-item-content">
    <button> // first button returned by ng-content </button>
    <button> // second button returned by ng-content </button>
    <button> // third button returned by ng-content </button>
</dxi-item>

But what I would like it to do, is to net the following html:

<dxi-item location='after' class="osii-item-content">
    <button> // first button returned by ng-content </button>
</dxi-item> 

<dxi-item location='after' class="osii-item-content">
    <button> // second button returned by ng-content </button>
</dxi-item>

<dxi-item location='after' class="osii-item-content">
    <button> // third button returned by ng-content </button>
</dxi-item>

Is there any known workaround for this issue?

Thanks!

Upvotes: 7

Views: 4441

Answers (2)

Daniel Gimenez
Daniel Gimenez

Reputation: 20494

As a rig you could put all of your buttons in templates in the parent component's content and then iterate through all the templates to display them as content.

App.component.html

<parent_component>
    <ng-template>
        <button> // first button </button>
    </ng-template>
    <ng-template>
        <button> // second button </button>
    </ng-template>
    <ng-template>
        <button> // third button </button>
    </ng-template>
</parent_component>

Parent.component.ts

export class ParentComponent {
  @ContentChildren(TemplateRef) templateRefs: QueryList<TemplateRef>;
}

Parent.component.html

<div *ngFor="let x of templateRefs">
  <dxi-item location='after' class="osii-item-content"> 
    <ng-container *ngTemplateOutlet="x"></ng-container>
  </dxi-item>
</div>

A better solution (that isn't exactly what you asked for) would be to pass a single template for your buttons and then an array with button content. In the example I pass an array of strings, but it certainly can be whole objects.

App.component.html

<parent_component [texts]=['first', 'second', 'third'>
    <ng-template let-x @BtnTemplate>
        <button> {{x}} </button>
    </ng-template>
</parent_compnent>

Parent.component.ts

export class ParentComponent {
  @Input() texts: string[];
  @ContentChild("BtnTemplate") btnTemplateRef: TemplateRef;
}

Parent.component.html

<div *ngFor="let x of texts">
  <dxi-item location='after' class="osii-item-content"> 
    <ng-container *ngTemplateOutlet="btnTemplateRef"
                  context: { $implicit: x }">
    </ng-container>
  </dxi-item>
</div>

Upvotes: 3

asoriano
asoriano

Reputation: 41

I guess what you're looking for is something like this: <ng-container *ngFor="let item of items"> <your-compo></your-compo> </ng-container> So you iterate over the items and generates required components. Don't be worried, ng-container won't be rendered, only your components will be.

Upvotes: 0

Related Questions