简体   繁体   中英

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

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 class="row align-items-center justify-content-center justify-content-md-between">
           {{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" class="accordion" ng-reflect-close-other-panels="true" aria-multiselectable="false"><!--container--><div class="card"><div role="tab" class="card-header" id="ngb-panel-0-header"><button type="button" class="btn btn-link collapsed" 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 class="card"><div role="tab" class="card-header" id="ngb-panel-1-header"><button type="button" class="btn btn-link collapsed" 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 class="card"><div role="tab" class="card-header" id="ngb-panel-2-header"><button type="button" class="btn btn-link collapsed" 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 class="mt-4" [closeOthers]="true">
        <ngb-panel *ngFor="let i of someList">
            <ng-template ngbPanelHeader>
                <div class="row align-items-center justify-content-center justify-content-md-between">
                    ... // use i
                </div>
            </ng-template>
            <ng-template ngbPanelContent >
             ...
        </ngb-panel>
    </ngb-accordion>

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>

I was Able to solve this using 'ng-container' Tag after the 'ngb-accordion' tag

<ngb-accordion class="accordion1" #acc="ngbAccordion">
  <ng-container *ngFor="let formshape of filterDataShapes">
    <ngb-panel *ngIf="formshape.type == 'select'">
      <ng-template ngbPanelContent>
      </ng-template>
    </ngb-panel>
  </ng-container>
</ngb-accordion>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM