akveo / nebular

:boom: Customizable Angular UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
https://akveo.github.io/nebular
MIT License
8.06k stars 1.51k forks source link

NbMenu is not activating items based on route correctly #2862

Open cperezabo opened 3 years ago

cperezabo commented 3 years ago

Issue type

I'm submitting a ...

Issue description

Current behavior: When updating [items] on NbMenu, the menu item matching the url is not being activated and stays greyed.

Expected behavior: CleanShot 2021-09-08 at 13 19 55@2x CleanShot 2021-09-08 at 13 19 46@2x

Sample App https://stackblitz.com/edit/nb-menu-bug-activated-route?file=src/app/home.component.ts

Other information:

Angular 11.2.9 Nebular 7.0.0

Kartikkman commented 3 years ago

Hi @cperezabo , Were you able to find the solution ? I am also looking for the solution of same .

PixelSam123 commented 3 years ago

I am also noticing weird behavior of the styling of this menu component based on active route, on version 8.0.0. It seems to not work when going to a home link '/', but works when going to a non-home link (like '/about'). And when you go from '/about' to '/' for example, the active style gets stuck on the 'About' item. Maybe it's because the active style isn't based on exact routes?

JudithMMolina commented 3 years ago

My problem is also with the routes and the menu. If I go to a page that does not match any of the ones described in the menu, the last visited item is still selected instead of none being active.

cperezabo commented 3 years ago

Hi @Kartikkman, no, I just released with that bug, because it doesn't affect the behavior of my system, but it's a clear UI bug and can be confusing for users! But I didn't want to hack into just to solve something that is a clear Nebular bug.

cperezabo commented 3 years ago

@JudithMMolina I have detected the same weird behavior in NbMenu, that maybe should be an issue itself.

  1. Click a menu item with i.e. link:"/photos", and the item will become active 👍
  2. Then do something that change the url to /photos/something and the item in menu will still be active. 👍
  3. Now reload the page and the link will be deactivated 🤯
JudithMMolina commented 3 years ago

@cperezabo There is an open issue from 3 years ago with my problem.

However, your case is different! In your case it should always be active, but you have not specified pathMatch: 'prefix'. If you do that it will no longer be disabled because it partially matches the url :)

cperezabo commented 3 years ago

Of course @JudithMMolina! I understand your case is different, I just wanted to contribute another situation which you have just solved 🚀🤪! Very thanks for the tip! 🤓

Maybe the bugs are related, why don't you refer your old issue to this so we push to get it fixed?

JudithMMolina commented 3 years ago

I have not tested the problem with this issue, but changes to @Input variables may not be detected.

I agree with you @cperezabo . The issue I was referring to is the following: #1277

cperezabo commented 3 years ago

The menu items change as expected, so the detection of the input is working. I have published an StackBlitz sample you can find in the first comment.

mekhal commented 3 years ago

I think my solution is not correct way to solve this issue but you can use this solution for temporary in case route is same current local url.

import { Component } from '@angular/core'; import { MENU_ITEMS } from './pages-menu'; import { NbMenuService } from '@nebular/theme';

@Component({ selector: 'ngx-pages', styleUrls: ['pages.component.scss'], template: '

', }) export class PagesComponent {

menu = MENU_ITEMS;

constructor(nbMenu: NbMenuService) {

nbMenu.onItemClick().subscribe((obj) => {

    document.querySelectorAll('nb-menu .menu-items a').forEach(q=>this.addActivetoMenuItem(obj.item.link));  // add class active to tag anchor on Nbmenu when click
});

}

addActivetoMenuItem(link){ document.querySelectorAll('nb-menu .menu-items a').forEach(q=>{if(link.includes(q.getAttribute("href")))q.classList.add("active"); else q.classList.remove("active");}); }

ngOnInit() {

setTimeout(() => {
  this.addActivetoMenuItem(window.location.href); 
}, 50); // this function for first load page or reload page

}

}

CrackerakiUA commented 2 years ago

hey, as temporary fix html:

<nb-menu tag="sidebar-menu" [items]="menu" #menuEl></nb-menu>

ts:

import {
    NavigationStart,
    Router,
    Event
} from '@angular/router';
import { NbMenuComponent } from '@nebular/theme';
@ViewChild('menuEl', {static: true}) menuEl: NbMenuComponent;
constructor(private router: Router) {
    this.router.events.subscribe((event: Event) => {
        if (event instanceof NavigationStart) {
            if (this.menuEl && this.menuEl.items) {
                for (let i = 0; i < this.menuEl.items.length; i++) {
                    this.menuEl.items[i].selected = false;
                }
            }
        }
    });
}
odisoedim commented 2 years ago

`isSubmenuClick() { this.nbMenu.onItemClick().subscribe(obj => { this.router.events.subscribe((event: Event) => { if (event instanceof NavigationEnd) { if (MENU_ITEMS) { for (let i = 0; i < MENU_ITEMS.length; i++) { MENU_ITEMS[i].selected = false; const menuLink = MENU_ITEMS[i].link;

          if (menuLink == event.url) {
            MENU_ITEMS[i].selected = true;
            this.updateItems();
          }
          if (MENU_ITEMS[i].children) {
            for (let index = 0; index < MENU_ITEMS[i].children.length; index++) {
              const subMenuLink = MENU_ITEMS[i].children[index].link;
              if (subMenuLink == event.url) {
                MENU_ITEMS[i].expanded = true;
                MENU_ITEMS[i].children[index].selected = true;
              } else {
                MENU_ITEMS[i].expanded = false;
                MENU_ITEMS[i].children[index].selected = false;
              }
              this.updateItems(); // 
            }
          }
        }
      }
    }
  });
});

}`

This is just for a temporary fix

alessandrogurgel commented 1 year ago

Many thanks @mekhal