Home > Blockchain >  ng-bootstrap: angular 13 accordion does not work with custom component
ng-bootstrap: angular 13 accordion does not work with custom component

Time:12-31

I am using ng-bootstrap accordion with angular 13. My problem is that the accordion entries do not show up when using a custom component in between.

My custom component when I first tried using it:

    <ngb-accordion [closeOthers]="true">
        <custom-panel *ngFor="let i of someList" [el]=i></custom-panel>
    </ngb-accordion>

custom-panel:

<ngb-panel>
    <ng-template ngbPanelHeader>
        <div >
           {{el}}
        </div>
    </ng-template>
    <ng-template ngbPanelContent>
        ...
    </ng-template>
</ngb-panel>

rendered nothing and the HTML just displayed an empty accordion. Then I tried changing the selector to selector: '[custom-panel]' and applied it to the ngb-panel.

        <ngb-panel *ngFor="let i of someList" custom-panel [el]="i">
        </ngb-panel>

which then resulted in the entries being shown but their content being empty.

empty entries

and the rendered HTML:

<ngb-accordion role="tablist"  ng-reflect-close-other-panels="true" aria-multiselectable="false"><!--container--><div ><div role="tab"  id="ngb-panel-0-header"><button type="button"  ng-reflect-ngb-panel-toggle="[object Object]" aria-expanded="false" aria-controls="ngb-panel-0"> <!--bindings={
 "ng-reflect-ng-template-outlet": null
}--></button><!--bindings={
 "ng-reflect-ng-template-outlet-context": "[object Object]"
}--></div><!--bindings={
 "ng-reflect-ng-if": "false"
}--></div><div ><div role="tab"  id="ngb-panel-1-header"><button type="button"  ng-reflect-ngb-panel-toggle="[object Object]" aria-expanded="false" aria-controls="ngb-panel-1"> <!--bindings={
 "ng-reflect-ng-template-outlet": null
}--></button><!--bindings={
 "ng-reflect-ng-template-outlet-context": "[object Object]"
}--></div><!--bindings={
 "ng-reflect-ng-if": "false"
}--></div><div ><div role="tab"  id="ngb-panel-2-header"><button type="button"  ng-reflect-ngb-panel-toggle="[object Object]" aria-expanded="false" aria-controls="ngb-panel-2"> <!--bindings={
 "ng-reflect-ng-template-outlet": null
}--></button><!--bindings={
 "ng-reflect-ng-template-outlet-context": "[object Object]"
}--></div><!--bindings={
...
 "ng-reflect-ng-template-outlet": null
}--></button><!--bindings={
 "ng-reflect-ng-template-outlet-context": "[object Object]"
}--></div><!--bindings={
 "ng-reflect-ng-if": "false"
}--></div><!--bindings={
 "ng-reflect-ng-for-of": ""
}--></ngb-accordion>

I am lost I don't understand I am not adding an element in between the accordion is it just so picky when rendering??. Using the custom-panel inline works, but that defeats the purpose of the component.

I might try creating the accordion with raw bootstrap. Edit: also didn't work because problems with data-target binding.

Edit: gave up on the custom component, did it dirty&inline

<ngb-accordion  [closeOthers]="true">
        <ngb-panel *ngFor="let i of someList">
            <ng-template ngbPanelHeader>
                <div >
                    ... // use i
                </div>
            </ng-template>
            <ng-template ngbPanelContent >
             ...
        </ngb-panel>
    </ngb-accordion>

CodePudding user response:

NgbAccordion expects NgbPanel as its direct ContentChild:

export class NgbAccordion implements AfterContentChecked {
  @ContentChildren(NgbPanel) panels: QueryList<NgbPanel>;
  ...
}

https://github.com/ng-bootstrap/ng-bootstrap/blob/369faa1f2634a445f136d8423c1da034ecc3b83c/src/accordion/accordion.ts#L208

So when we try to do something as below, NgPanel is no more a ContentChild of NgbAccordion and hence it doesn't work.

<ngb-accordion [closeOthers]="true">
   <custom-panel *ngFor="let i of someList" [el]=i></custom-panel>
</ngb-accordion>
  • Related