I'm trying to determine the 'right' way to solve this problem.
I have a menu with sub-menu's. I want to animate (using jQuery transitions) a slide-up & a slide-down effect when my route changes.
I understand I shouldn't manipulate my DOM from my controller as this is a bad-practice. Should I be using directives that listen to route changes? Services?
(example)
ul
li
li
li
ul
li
li
I'm trying to determine the 'right' way to solve this problem.
I have a menu with sub-menu's. I want to animate (using jQuery transitions) a slide-up & a slide-down effect when my route changes.
I understand I shouldn't manipulate my DOM from my controller as this is a bad-practice. Should I be using directives that listen to route changes? Services?
(example)
ul
li
li
li
ul
li
li
Share
Improve this question
edited Apr 20, 2013 at 9:46
Trinimon
14k9 gold badges46 silver badges61 bronze badges
asked Apr 20, 2013 at 9:22
Casey FlynnCasey Flynn
14k26 gold badges108 silver badges196 bronze badges
2 Answers
Reset to default 6You should take a look at ngAnimate. There is a tutorial here
You will then be able to specify animations decleratively on elements that should be animated.
For example you might specify "enter" and "leave" animations on a element that is dynamically shown/hidden based on a value in the scope. Animations can then be specified in CSS3 (remended), or using jQuery, mootools and other libraries.
<li ng-repeat="item in parent.items" ng-animate="'slide'" ng-show="parent.open">{{item.text}}</li>
EDIT: This API is deprecated but it is a even better API and and similar approach. Read more about it here: http://www.yearofmoo./2013/08/remastered-animation-in-angularjs-1-2.html.
This is very similar to: Slide up/down effect with ng-show and ng-animate
This directive: https://github./EricWVGG/AngularSlideables will create an easy API to add sliding to any elements.
If you're willing to you jQuery: https://github./onokumus/metisMenu can create expandable menus for you.
If you're populating your menu from the backend, something like the following in your menu controller will let you set up your navigation and then instantiate the menu.
$scope.response = null;
$http.get(ENV.api.endpoint+"/menu").
then(function(response) {
$scope.navItems = response.data;
$timeout(function() {
jQuery('.metismenu').metisMenu();
});
}, function(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
My navigation angular code is: (Note the :: in navItems makes it only populate one time.)
<ul side-navigation class="nav metismenu" id="side-menu" >
<li ui-sref-active="active" ng-repeat="Item in ::navItems.Regular">
<a ui-sref="{{Item.state}}"><i class="fa {{Item.icon}}"></i> <span class="nav-label">{{Item.title}}</span></a>
</li>
<li ng-class="{active: $state.includes(Item.state)}" ng-repeat="Item in ::navItems.DropDown">
<a href=""><i class="fa" ng-class="Item.icon"></i> <span class="nav-label">{{Item.title}}</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse" ng-class="{in: $state.includes(Item.state)}">
<li ui-sref-active="active" ng-repeat="Subitem in Item.items">
<a ui-sref="{{Subitem.state}}"><i class="fa {{Subitem.icon}}"></i> {{Subitem.title}}</a>
</li>
</ul>
</li>
</ul>
The JSON then looks like:
{
"Regular": [
{
"title": "Directory",
"icon": "fa-archive",
"state": "directory"
}
],
"DropDown": [
{
"title": "Accounting",
"icon": "fa-dollar",
"state": "accounting",
"items": [
{
"title": "Approve Time",
"state": "accounting.staffTimeclockActApprove",
"icon": "fa-check-circle-o"
},
{
"title": "Notify Time",
"state": "accounting.staffTimeclockActNotify",
"icon": "fa-envelope-o"
}
]
}
]
}