Topic: mdb-navbar dropdown doesn't work with ng-template

bitmads premium asked 4 years ago


*_Expected behavior_*The menu dropdown works

Actual behavior

It doesn't work. Appears in the source code as an invisible element (display:none), and stays invisible when I click on the dropdown trigger.When I use the raw example code of the website, it works as expected, so I think the issue with that I'd print them recursively using ng-template.

Resources (screenshots, code snippets etc.)

  <mdb-navbar SideClass="navbar navbar-expand-md fixed-top navbar-dark bg-ocean shadow-none">

    <mdb-navbar-brand><a class="navbar-brand" href="/"><img src="/templates/default/logo.svg?ver=3" height="40"></a></mdb-navbar-brand>
    <links>
      <ul class="navbar-nav mr-auto">
        <li class="nav-item" *ngFor="let item of menu | toArray" [ngClass]="{dropdown: item.children}" [attr.dropdown]="item.children ? 'dropdown' : false">
          <ng-container *ngTemplateOutlet="menu_level_1; context:{ $implicit: item}"></ng-container>
        </li>
      </ul>

      <ng-template #menu_level_1 let-item>
        <a routerLink="{{item.path}}" class="nav-link waves-light" mdbWavesEffect *ngIf="!item.children">{{item.title}}</a>

        <a mdbWavesEffect type="button" class="nav-link dropdown-toggle waves-light" mdbWavesEffect *ngIf="item.children">
          {{item.title}}<span class="caret"></span>
        </a>
        <div class="dropdown-menu dropdown dropdown-primary" role="menu">
          <a class="dropdown-item waves-light" mdbWavesEffect href="#">Action</a>
          <a class="dropdown-item waves-light" mdbWavesEffect href="#">Another action</a>
          <a class="dropdown-item waves-light" mdbWavesEffect href="#">Something else here</a>
          <div class="divider dropdown-divider"></div>
          <a class="dropdown-item waves-light" mdbWavesEffect href="#">Separated link</a>
        </div>
      </ng-template>
    </links>
  </mdb-navbar>

The object from the js file:


    this.menu = {
  'home' : {title:'Home',path:'/'},
  'places' : {
    title:'Places',
    children:{
      'locations': { title:'MTP Locations',path:'/checklists/locations' },
      'restaurants': {
        title: 'Restaurants',
        children:{
          'restaurants':{ title: 'Restaurants (**+)',path:'/checklists/restaurants' },
          'restaurantstop100':{ title: 'Restaurants (Top 100)',path:'/checklists/restaurants' }
        }
      },
    }
  },
  'rankings' : {
    title: 'Rankings',
    children:{
      'sliceanddice': { title: 'Slice and Dice', path: '/rankings'},
      'hallsoffame': { title: 'Halls of Fame', path: '/milestones/locations'},
    }
  },
  'contact' : { title: 'Contact',path: '/contact' }
}

Arkadiusz Idzikowski staff commented 4 years ago

Thanks for letting us about this problem, we will take care of that.


Arkadiusz Idzikowski staff answered 4 years ago


I'm not sure what is the exact use case for the approach with ngTemplateOutlet here. The dropdown content won't be lazy loaded anyway, it will be added to the dom on the component initialization.

It looks like dropdownToggle directive must be a child of the element with dropdown directive on component initialization. You can try to move a tags from the ng-template to the li container. You should also add dropdownToogle directive to the a element and dropdown directive to the li element (because it's not added correctly with the [attr.dropdown] syntax). I slightly changed menu object to use it with ngFor, beause I didn't have access to your toArray pipe, but I think I achieved the same results. Here is working example:

<links>
  <ul class="navbar-nav mr-auto">
    <li dropdown class="nav-item" *ngFor="let item of menu" [ngClass]="{dropdown: item.children}">
        <a class="nav-link waves-light" mdbWavesEffect *ngIf="!item.children">{{item.title}}</a>

        <a dropdownToggle type="button" class="nav-link dropdown-toggle waves-light" mdbWavesEffect *ngIf="item.children">
          {{item.title}}<span class="caret"></span>
        </a>
      <ng-container *ngTemplateOutlet="menu_level_1; context:{ $implicit: item}"></ng-container>
    </li>
  </ul>

  <ng-template #menu_level_1 let-item>
    <div class="dropdown-menu dropdown dropdown-primary" role="menu">
      <a class="dropdown-item waves-light" mdbWavesEffect href="#">Action</a>
      <a class="dropdown-item waves-light" mdbWavesEffect href="#">Another action</a>
      <a class="dropdown-item waves-light" mdbWavesEffect href="#">Something else here</a>
      <div class="divider dropdown-divider"></div>
      <a class="dropdown-item waves-light" mdbWavesEffect href="#">Separated link</a>
    </div>
  </ng-template>
</links>


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Premium
  • Premium support: Yes
  • Technology: MDB Angular
  • MDB Version: 8.6.0
  • Device: PC
  • Browser: Chrome
  • OS: Windows 10
  • Provided sample code: No
  • Provided link: No