I just added ui-bootstrap to my package based on the angular-fullstack-generator. Before that I used the following code to collapse the navbar on small devices when the route changes:
$rootScope.$on('$stateChangeSuccess', function (event, next) {
// collapse navbar
angular.element('.navbar-collapse').collapse('hide');
});
This is not possible anymore because of the directives as I understand from #1672 but how I can manually collapse the navbar then?
Thanks in advance,
Michael
You can collapse the navbar on click (it feels more natural to me) simply by adding (or enhancing) the ng-click handler on each <a>:
<a ng-href="{{item.link}}" ng-click="isCollapsed=true">{{item.title}}</a>
{{ 'LANG_BUTTON_EN' | translate }}
If you really want it after the $stateChangeSuccess event, add the same event listener to your navbar.controller.js (no need to listen to the $rootScope though - or is this event limited there? I do not know so please use caution):
angular.module('jayMapApp')
.controller('NavbarCtrl', function ($scope, $location, $translate, Auth) {
...
$scope.$on('$stateChangeSuccess', function (event, next) {
$scope.isCollapsed = true;
});
...
Related
I am trying to do some functionality on $stateChangeSuccess.
$rootScope.$on('$stateChangeSuccess', function(event, toState) {
$rootScope.guestNav.push(toState);
});
And the above code should not work when I click browser back button that is on popstate event. Please help me to solve this issue. Or provide me a feasible solution.
Did you try to use new life cycle events? E.g.
.run(($transitions, $state, $injector) => {
'ngInject';
$transitions.onSuccess({ to: 'app.home' },
() => console.log('accessing to app home state'));
});
I want to run a function on each route changes in angular.
Is there any event like OnRouteChange in angular?
yes there are some events like,
$routeChangeStart, $routeChangeSuccess, $routeChangeError, $routeUpdate
$routeChangeStart -> Broadcasted before a route change. At this point the route services starts resolving all of the dependencies needed for the route change to occur. Typically this involves fetching the view template as well as any dependencies defined in resolve route property. Once all of the dependencies are resolved $routeChangeSuccess is fired.
for EX:
app.run(function($rootScope, $location) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
});
$rootScope.$on('$routeChangeSuccess', function () {
});
$rootScope.$on('$routeChangeError', function () {
});
})
here is the DOC
here is a good article.
I am not sure how this can be achieved in Angular. I want to add and remove CSS class on route change. I am trying to Show and Hide vertical menu. Currently I am using ui-route. Any Suggestion or link to example would be appreciated or any other suggestion on different approach to my problem is also welcome
Easiest and most efficient way:
angular.module(...).run(function($rootScope, $state) {
$rootScope.$state = $state;
});
<div ng-if="$state.contains('someState')">...</div>
This will remove the DOM which will improve performance if the menu has lots of bindings.
However, I constantly tell people to consider leveraging named views for navigation:
<body>
<nav ui-view="nav"></nav>
<div class="container" ui-view></div>
</body>
$stateProvider.state('home', {
views: {
'nav#': {
templateUrl: 'nav.html'
}
'': {
// normal templateUrl and controller goes here.
}
}
});
The cool part about this is that children states can override and control what nav file to use, and can even setup resolves and controllers that share data between the nav and the content. No directives/services needed!
Finally, you can do these too:
<nav ng-show="$state.contains('somestate')"></nav>
<nav ng-class="{someClass:$state.contains('somestate')}"></nav>
Alternatively checkout ui-sref-active
All of my suggestions primarily assume you're using UI-Router since it's the best!
Try this:
app.run(function ($rootScope) {
$rootScope.$on("$stateChangeStart", function(event, toState, fromState){
if (toState.url === "/path") {
$('div').addClass('className');
} else {
$('div').removeClass('className');
}
});
});
You can register the route changed and add this css to your DOM:
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
// Add your logic, for instance:
$('body').addClass('hide-menu');
});
Obviously there are events raised before the route has been changed: "$locationChangeStart", here.
/Edit/ - Better approach
Also I would rather using the ng-class attribute and simple bind a certain value from your main controller to it.
app.controller('MainController', function ($scope) {
$scope.toggleMenu = function(isToShow) {
$scope.isVisibleMenu = isToShow == true;
};
});
then in your html:
<!-- Menu toggle button-->
<button ng-click="toggleMenu()"></button>
<div class="toggleable-menu" ng-class="{'visible-menu': isVisibleMenu}">
<!-- The menu content-->
</div>
and the simplest CSS possbile (you can obviously add animations or any other thing to toggle this menu.)
.toggelable-menu {
display: none;
}
.toggelable-menu.visible-menu {
display: block;
}
I'm want to display a loading icon in my view, but I doesn't seem to work..
My view renders when my $resource in the resolve is loaded.
.run(['$rootScope', '$state', '$stateParams', function () {
$rootScope.$on('$stateChangeStart', function () {
console.log('start');
$rootScope.spinner = true;
});
$rootScope.$on('$stateChangeSuccess', function () {
console.log('end');
$rootScope.spinner = false;
});
}])
Can't set the spinner because my view isn't loaded yet..
How am I supposed to ng-show on my spinner div then..?
You can put the spinner to be outside of any view. That way you don't need to include it in any template but you'll still be able to control it with ng-show and watching state changes like you did.
I've solved it by putting my loading div outside of the ui-view.
Because it is outside the controller of the ui-view, I can just use the $rootScope.loading here.
<div ng-show="loading" class="loader">
<p>Loading, please wait...</p>
</div>
<div ui-view ng-class="{transparent: loading}"></div>
I'm using angular-ui modal in my webapp. one of models display many links (anchor elements) that navigate to various parts of the app. the modal can be closed as usual with modal.dismiss() or modal.close(). but I need it to close when someone navigate out of it with clicking an anchor? usually (not angular) I could just attach an event to all the anchor clicks and close the modal from there. but in angular It seems somewhat complicated and not very "angularish" - Any ideas/directions on how to implement this?
e.g: I'm using angular-ui-router so if this can be solved through the routes It would also solve my problem.
Thanks!
Angular-ui-router fires events when a state change has occurred, so in your controller you could do something like:
$scope.currentModal = undefined;
// whenever a modal opens, ensure it is assigned to the $scope.currentModal. Not clear how
// you are managing your modals at the moment.
// this event-listener closes the current modal (if any)
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
if ($scope.currentModal) {
$scope.currentModal.dismiss();
}
})
Use $modalStack.dismissAll() to close any modalbox when state changes.
angular.module('myApp').controller('AppCtrl', ['$scope', '$rootScope', '$modal', '$modalStack',
function ($scope, $rootScope, $modal, $modalStack) {
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams, options){
$modalStack.dismissAll();
});
}
]);