Open ashwanikumar415 opened 7 years ago
how about this issue? i undergo a same question.
Resolved this issue by writing a decorator for directive maMenubar (https://github.com/marmelab/ng-admin/blob/master/src/javascripts/ng-admin/Main/component/directive/maMenuBar.js)
If you observe in maMenubar.js, whenever "locationChangeSuccess" event is fired render() is invoked which causes the whole left menu to be redrawn again. That causes the flicker. So one of the fixes could be calling a method like updateLeftMenuStyling() which would just highlight the activeMenu item and close the other menu items (if at all some of them are opened) using javascript instead of render(). like below `var listener = $rootScope.$on('$locationChangeSuccess', function() {
scope.path = $location.path();
updateLeftMenuStyling(activeMenu, activeParentMenu);
//render();
});`
function updateLeftMenuStyling(menu, parentMenu) {
var elements = getElementsForMenu(menu);
elements.allUlElements.addClass('collapsed');
elements.allArrowElements.removeClass('glyphicon-menu-down');
elements.allArrowElements.addClass('glyphicon-menu-right');
if (parentMenu) {
openMenu(parentMenu);
}
elements.allAnchorTags.removeClass('active');
if(menu.link()) {
elements.anchorTag.addClass('active');
}
elements.anchorTag.blur();
}
function getElementsForMenu(menu) {
let parentLi;
angular.forEach(element.find('li'), function(li) {
const liElement = angular.element(li);
if (liElement.attr('data-menu-id') === (menu.uuid).toString()) {
parentLi = liElement;
}
});
const anchorTag = (parentLi) ? parentLi.find('a')[0] : null;
const ulElements = (parentLi) ? parentLi.find('ul') : null;
const arrowElement = (anchorTag) ? anchorTag.getElementsByClassName('arrow')[0] : {};
return {
arrow: angular.element(arrowElement),
allArrowElements: angular.element(element.find('span.arrow')),
ul: (ulElements) ? ulElements.eq(0) : {},
anchorTag: angular.element(anchorTag),
allAnchorTags: angular.element(element.find('a')),
allUlElements: angular.element(element.find('ul'))
};
}`
` scope.activateLink = function (menu, parentMenu) {
activeMenu = menu;
activeParentMenu = (parentMenu) ? parentMenu : null;
if (!menu.link()) {
return;
}
if (menu.autoClose()) {
openMenus = [];
}
};`
<div class="navbar-default sidebar" role="navigation" compile="menu.template()">
<div class="sidebar-nav navbar-collapse collapse" uib-collapse="$parent.isCollapsed">
<ul class="nav" id="side-menu">
<li class="entities-repeat" ng-repeat="(key, firstLevelMenu) in ::menu.children()" data-menu-id="{{ ::firstLevelMenu.uuid }}" compile="firstLevelMenu.template()">
<a ng-if="::firstLevelMenu.hasChild()" ng-click="toggleMenu(firstLevelMenu)" ng-class="::{'active': firstLevelMenu.isActive(path)}">
<span compile="::firstLevelMenu.icon()"><span class="glyphicon glyphicon-list"></span></span>
{{ firstLevelMenu.title() | translate }}
<span class="glyphicon arrow" ng-class="::{'glyphicon-menu-down': isOpen(firstLevelMenu), 'glyphicon-menu-right': !isOpen(firstLevelMenu) }"></span>
</a>
<a ng-if="::!firstLevelMenu.hasChild()" href="#{{ firstLevelMenu.link() }}" ng-click="activateLink(firstLevelMenu)" ng-class="::{'active': firstLevelMenu.isActive(path)}">
<span compile="::firstLevelMenu.icon()"><span class="glyphicon glyphicon-list"></span></span>
{{ firstLevelMenu.title() | translate }}
</a>
<ul ng-if="::firstLevelMenu.hasChild()" class="nav nav-second-level collapsible" data-menu-id="{{ ::firstLevelMenu.uuid }}" ng-class="::{'collapsed': !isOpen(firstLevelMenu) }">
<li ng-repeat="secondLevelMenu in ::firstLevelMenu.children()" data-menu-id="{{ ::secondLevelMenu.uuid }}" compile="secondLevelMenu.template()">
<a href="#{{secondLevelMenu.link()}}" ng-click="activateLink(secondLevelMenu, firstLevelMenu)" ng-class="::{'active': secondLevelMenu.isActive(path)}">
<span compile="::secondLevelMenu.icon()"><span class="glyphicon glyphicon-list"></span></span>
{{ secondLevelMenu.title() | translate }}
</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
If you use any comparator , you will observe the only difference between menubar.html ( https://github.com/marmelab/ng-admin/blob/master/src/javascripts/ng-admin/Main/view/menuBar.html) and the customizedMenubar.html is
ng-click="activateLink(secondLevelMenu, firstLevelMenu)
And some renaming of iterator variables in ng-repeat from menu to firstLevelMenu and SecondLevelMenu.
Note: The above solution will not highlight the relevant menu item when a user changes the address bar to point to some other menu item. To fix that change locationChangeSuccess listener to make it capable to get activeMenu item either based on address bar of browser or from scope.activateLink(this was already done above )
` var listener = $rootScope.$on('$locationChangeSuccess', function() {
scope.path = $location.path();
if (!activeMenu) {
const menuObj = Utils.getActiveAndParentMenuByLocation(scope.menu.children(), scope.path);
activeMenu = menuObj.activeMenu;
activeParentMenu = menuObj.activeParentMenu;
}
updateLeftMenuStyling(activeMenu , activeParentMenu);
activeMenu = null;
activeParentMenu = null;
});
` where Utils.getActiveAndParentMenuByLocation() method will use Array.find() to get activeMenu and activeParentMenu object by comparing location.path === menu['_link']
Thanks for coming this far and reading it :)
Any fix for this issue?
Easiest workaround for this issue not to reproduce is setting autoClose(false) like below
var master = nga.menu(); master.autoClose(false);
Assuming master holds all the other submenu objects
But what if I want to use auto close option. I used your previous solution in ng-admin source, it worked. but I wanted to know if there was plan to solve this issue in the original ng-admin repository.
Above solutions don't work for me. Found out my solution for this, add this css
.collapsed {
height: 0;
}
Left panel menu minimises and maximises always for a fraction of second every time when page is refreshed or any menu item is selected plunkr : http://plnkr.co/edit/yTMTofsjfw4XT4EOzint?p=preview
Note: To see issue occuring (especially page refresh case) download the zip from plunkr and run the index.html page individually GIF :
Expected behavior: Only already opened menu item should remain open with no flickering
Actual behavior: 8/10 times flicker happens, gets worse when the menu list is lengthy