Using ngRoute once can hook up in event: $routeChangeStart and do different actions ...
app.run(function ($rootScope, $location) {
$rootScope.$on("$routeChangeStart", function (event, next, current) {
................
Is it possible to achieve the same using UI-Router?
Yes it's possible:
$rootScope.$on("$stateChangeStart",
function (event, toState, toParams, fromState, fromParams) {
Or just use
$scope.$on("$stateChangeStart",...);
If you want this to be triggered on a single page.
Check this answer here, that's the correct way to fix it. Removing all listeners could have unknown effects as there might be other places where listeners are added. You need to remove the one you added, not all of them.
Check this issue: Angular $rootScope $on listeners in 'destroyed' controller keep running
Copying code here for completeness too:
animateApp.controller('mainController', function($scope, $rootScope, service) {
$scope.pageClass = 'page-home';
var unregister = $rootScope.$on('service.abc', function (newval) {
console.log($scope.$id);
});
$scope.$on('$destroy', unregister);
});
Related
My AngularJs run block does not execute the handler function when the application changes routes, at least that is what I think. I tried putting a simple console log to test and it does not log anything. The final objective is to be a route interceptor checking if the route needs authentication.
Link for github repository https://github.com/guilinden/authenticatedCRUD
(function(){
angular
.module('app')
.run(function ($rootScope, $location) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
var requireLogin = toState.data.requireLogin;
if(requireLogin){
event.preventDefault();
$location.path('/home');
}
});
});
})();
$stateChange* events are deprecated
The $stateChange* events are deprecated in 1.0. They are replaced with the $transitions.on* transition hooks.
However, they can be re-enabled for backwards compatibility by including stateEvents.js and depending on the 'ui.router.state.events' angular module.
<script src="stateEvents.js">
var myApp = angular.module('myApp', ['ui.router', 'ui.router.state.events']);
See UI-router Issue #2720 - $stateChangeStart not being fired on v1.0
There should be a app not defined error in your console. You are missing empty dependencies
angular
.module('app',[])
also change it as, $location as a dependency to run,
.run(function ($rootScope,$location) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
I have a function validateSesion that i need to call every time a controller is executed.
There is a way to trigger the function without putting the call to the function in all the controllers?
The way I would recommend accomplishing such a call would be to create event handlers for your route changes. This way every time you change your route or state (if you are using ui-router) you can run your code.
You would place this in your app's run function and attach the event handlers to the $rootScope as shown below:
angular.module('app', [
//Your Dependencies Here
]).run(init);
function init($rootScope, sessionService) {
//ngRoute
$rootScope.$on('$routeChangeStart', function (angularEvent, next, current) {
sessionService.validateSession();
});
//ui-router
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
sessionService.validateSession();
});
}
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'm trying to adapt the answer give in this similar question How to handle anchor hash linking in AngularJS. I need to be able to use it with ui-router. I've tested anchor scrolling as a clickable function in my controller and that is working. Here is the code for that
$scope.anchor = function () {
console.log('test');
$location.hash('comments');
$anchorScroll();
};
If I try to invoke that function immediately nothing happens
$scope.anchor();
If I try to invoke it on a $stateChangeSuccess nothing happens. I threw in a log for sanity and that is firing. I also tried a trick to prevent further routing logic from kicking in. It was mentioned in the linked post but I'm not sure if it's necessary for my case.
app.run(function ($rootScope, $location, $stateParams, $anchorScroll) {
// allow anchorScrolling
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
console.log('stateChangeSuccess');
var old = $location.hash();
$location.hash('comments');
$anchorScroll();
//reset to old to keep any additional routing logic from kicking in
$location.hash(old);
});
});
I'm guessing that I'm running into race conditions or my anchor scroll is somehow triggering another route change. But I can't figure out how to track these issues down. Any thoughts?
EDIT: Update I removed the $location.hash(old); and put the rest of the $anchorScroll pieces into a timeout function and it's now working. I also added in the $stateParams.scrollTo to make this useable with query params. Any ideas as to what is causing my race condition and how this might be solved without a $timeout function?
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
console.log('stateChangeSuccess');
$timeout(function() {
$location.hash($stateParams.scrollTo);
$anchorScroll();
}, 300);
});
From $anchorScroll documentation
It also watches the $location.hash() and scrolls whenever it changes to match any anchor. This can be disabled by calling $anchorScrollProvider.disableAutoScrolling().
Try removing $location.hash(old);
If that fixes it, use $anchorScrollProvider.disableAutoScrolling() to disable it reacting to another state change.
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();
});
}
]);