How can I create a recursive navigation tree using ng-bootstrap's NgbNav?

Discussão em 'Angular' iniciado por PingZing, Fevereiro 27, 2025.

  1. PingZing

    PingZing Guest

    I'm trying to use ng-bootstrap's ngbNav directive to create a navigation tree of arbitrary depth. What I have almost works, but I'm fighting with what are think are Angular's template scoping around injection contexts. When I try to load what I have at the moment, I get the following error:


    Component update failed: R3InjectorError(Standalone[_AppComponent])[_NgbNavItem -> _NgbNavItem -> _NgbNavItem]: NullInjectorError: No provider for _NgbNavItem!
    ​

    I'm using Angular v19, and standalone components. I'm using ng-bootstrap v18.0.0.

    Here's my template code:

    <nav ngbNav #nav="ngbNav" orientation="vertical" class="nav-pills">
    <ng-container *ngTemplateOutlet="recursiveTree; context: { list: urlInfoTable, depth: 0 }"></ng-container>
    </nav>

    <ng-template #recursiveTree let-list="list" let-depth="depth">
    <ng-container *ngFor="let urlInfo of list">
    <a *ngIf="urlInfo.isLeaf" ngbNavLink [routerLink]="[urlInfo.url]">{{ urlInfo.name }}</a>
    <ul *ngIf="urlInfo.children$ !== null">
    <ng-container
    *ngTemplateOutlet="recursiveTree; context: { list: urlInfo.children$ | async, depth: depth + 1 }"
    ></ng-container>
    </ul>
    </ng-container>
    </ng-template>

    <main id="sideNavContent">
    <router-outlet />
    </main>


    And the relevant bits from my component code:

    export class NavigationComponent {
    public urlInfoTable: UrlInfo[] = [
    { id: "1", url: "/", name: "Home", isLeaf: true, children$: null },
    { id: "2", url: "/users/self", isLeaf: true, name: "Self", children$: null },
    { id: "3", name: "Organizations", isLeaf: false, children$: this.getOrgs() }
    ];
    }

    interface UrlInfo {
    id: string;
    isLeaf: boolean;
    name: string;
    url?: string;
    children$: Observable<UrlInfo[]> | null;
    }


    ...and the getOrgs() method returns a placeholder Observable<UrlInfo[]> at the moment.

    I have noticed that if I remove ngbNavLink from the template, the error goes away (along with all the Nav functionality, of course). Looking at ng-bootstrap's code for the NgbNavLink directive, it even makes sense--the first thing it tries to do is resolve the NgbNavItem dependency. What I don't understand is how--if at all?--can I ensure that it has the required context here?

    Continue reading...

Compartilhe esta Página