What is your product version? 10 Latest
What is your product type (Angular or MVC)? ASP.net Core and Angular
What is product framework type (.net framework or .net core)? .NET5
What is ABP Framework version? The one that comes up with ASP.NET and Angular v10.
I am trying to use dynamic menu on the left hand side. I have searched your support side and tried to utilise what other people have done but I am struggling to implement it. This is what I have done so far:
Declared a global variable in app-navigation-service.ts
.
myAppMenu: AppMenu = new AppMenu('MainMenu', 'MainMenu', []);
I am calling my web api to get the menu from the server in getMenu()
function of app-navigation-service.ts
getMenu(): AppMenu {
this._myMenuService.getAllGrantedMenus(1, 1, 2)
.subscribe(result => {
console.log(result);
this.myAppMenu = result;
abp.event.trigger('myMenuLoaded', this.myAppMenu);
});
return this.myAppMenu;
}
In side-bar-menu.component.ts
I am registering the event and your code is being used to call getMenu()
function. The code is shown below.
ngOnInit() {
this.menuLoaded();
this.menu = this._appNavigationService.getMenu();
this.currentRouteUrl = this.router.url.split(/[?#]/)[0];
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd))
.subscribe(
(event) =>
(this.currentRouteUrl = this.router.url.split(/[?#]/)[0])
);
}
menuLoaded(): void {
abp.event.on('myMenuLoaded', function (menu) {
console.log("EVENT IS FIRED");
console.log(menu);
this.menu = menu;
});
}
The above event is fired, but the menu is blank. I guess it is because the html and angular templates are executed before the menu data is returned. I am struggling to re-render the menu as it should be re-rendered when event is fired. Can you please help?
6 Answer(s)
-
0
The above event is fired, but the menu is blank.
menuLoaded(): void { abp.event.on('myMenuLoaded', function (menu) { console.log("EVENT IS FIRED"); console.log(menu); this.menu = menu; debugger; // Can you please add debugger here and check if `this.menu` defined here. }); }
If it is defined, you can add a
ngIf
in html side to wait for menu. side-bar-menu.component.html<!-- BEGIN: Aside Menu --> <div [class]="'aside-menu-wrapper aside-menu-' + currentTheme.baseSettings.menu.asideSkin" id="kt_aside_menu_wrapper" *ngIf="menu"> <!----....----> </div> <!-- END: Aside Menu -->
-
0
@musa.demir Thank you for your reply.
When I add
*ngif="menu"
, I received the below error.`
<div [class]="'aside-menu-wrapper aside-menu-' + currentTheme.baseSettings.menu.asideSkin" id="kt_aside_menu_wrapper" *ngif="menu"> <div #asideMenu ktMenu [options]="menuOptions" [perfectScrollbar]="{wheelPropagation: false}" [ngStyle]="{'max-height': '90vh', 'position': 'relative'}" id="kt_aside_menu" class="aside-menu scroll" [attr.data-menu-vertical]="1" [attr.data-menu-scroll]="ui.getIsMenuScrollable() ? 1 : 0" [attr.data-menu-dropdown]="ui.isSubmenuToggleDropdown() ? 1 : 0" (mouseenter)="mouseEnter($event)" (mouseleave)="mouseLeave($event)" [class]="ui.getLeftAsideClass()"> <ul class="menu-nav"> <li class="menu-item mb-5" aria-haspopup="true" data-ktmenu-submenu-toggle="hover" *ngIf="currentTheme.baseSettings.menu.searchActive"> <menu-search-bar></menu-search-bar> </li> <ng-container [ngTemplateOutlet]="menuListTemplate"></ng-container> </ul> </div> </div> <!-- END: Aside Menu -->`
Yes, this.menu contains data when event is fired, please see below the console output.
There must be a way of re-rendering menu.
-
0
Just an update, I was using ngif instead of ngIf (note capital I), after changing it to capital I, I don't receive error but menu is still not displayed, even though it contains the data. I don't know if menu is displayed this way after ngOnInit, there may be a different way of re-rendering i.e calling some method etc. I am not be sure though, can you think of anything else, as it seems like a common functionality?
-
0
I have fixed this issue, thanks to @musa.demir for asking me to use
*ngIf
. I am showing my implementation below so that it may help someone else if they get stuck.In
side-bar-menu.component.html
add*ngIf="menu"
, note capital I of If.<!-- BEGIN: Aside Menu --> <div [class]="'aside-menu-wrapper aside-menu-' + currentTheme.baseSettings.menu.asideSkin" id="kt_aside_menu_wrapper" *ngIf="menu"> <div #asideMenu ktMenu [options]="menuOptions" [perfectScrollbar]="{wheelPropagation: false}" [ngStyle]="{'max-height': '90vh', 'position': 'relative'}" id="kt_aside_menu" class="aside-menu scroll" [attr.data-menu-vertical]="1" [attr.data-menu-scroll]="ui.getIsMenuScrollable() ? 1 : 0" [attr.data-menu-dropdown]="ui.isSubmenuToggleDropdown() ? 1 : 0" (mouseenter)="mouseEnter($event)" (mouseleave)="mouseLeave($event)" [class]="ui.getLeftAsideClass()"> <ul class="menu-nav"> <li class="menu-item mb-5" aria-haspopup="true" data-ktmenu-submenu-toggle="hover" *ngIf="currentTheme.baseSettings.menu.searchActive"> <menu-search-bar></menu-search-bar> </li> <ng-container [ngTemplateOutlet]="menuListTemplate"></ng-container> </ul> </div> </div> <!-- END: Aside Menu -->
Replaced
this.menu = this._appNavigationService.getMenu();
inngOnInit()
ofside-bar-menu.component.ts
with the code shown below. Replace your service and method names. Also, don't forget to inject your service in the constructor ofside-bar-menu.component.ts
this._myMenuService.getAllGrantedMenus(1, 1, 2) .subscribe(result => { console.log(result); this.menu = result; });
-
0
Hi,
The menu is loaded fine as per my previous comment, however, sometimes I need to progammatically refresh menu so that it gets the latest data from the server. What is the best way to refresh the menu?
I tried to use events for this purpose but when event is triggered, my global function inside
side-bar-menu.component.ts
is not available inside the trigged code so I can't simply use the code below.loadMyMenu(myParameterForMenuSelection: number): void { //Code here for getting the menu from the server. } reloadMenu(): void { abp.event.on('myParameterForMenuSelectionChanged', function (myParameterForMenuSelection) { console.log("EVENT IS FIRED"); console.log(myParameterForMenuSelection); this.loadMyMenu(myParameterForMenuSelection);//I get error here that loadMyMenu is not a function }); }
I receive the below error when event is fired.
ERROR TypeError: this.loadMyMenu is not a function
What is the best way to refresh the menu?
-
0
Hi @learner29
Using events is the way for handling such changes. Change your event definition like this;
abp.event.on('myParameterForMenuSelectionChanged', () => (myParameterForMenuSelection) { console.log("EVENT IS FIRED"); console.log(myParameterForMenuSelection); this.loadMyMenu(myParameterForMenuSelection);//I get error here that loadMyMenu is not a function });