Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS with ui.router: reload page when clicking the same state link

I just got a request from our QA team, which I think sounds ridiculous. Here it goes: suppose you are already on the 'about' state/page in the angular-based app, and when you click on the 'about' state url again from the top menu, you want the 'about' page to reload. The about page does not fetch data from anywhere, by the way, a reload is simply equivalent to a blink.

For the state config in my angular app is like this:

.state('about', {
  url: '/about',
  templateUrl: '/path/to/about.html',
  controller: 'aboutCtrl as aboutView'
});

And in the top menus, we have a link pointing to this state:

<a ui-sref="about">About</a>

I have tried many things to get this to work: clicking the link triggers the reload of the same state.

Things like $state.go('about', {}, {reload: true}); or $state.transitionTo('about', {}, {reload: true}); don't work, because the links are static.

One last resort I am currently trying is to manipulate the reload thing in the run phase of Angular by listening to '$stateChangeSuccess' event, but I don't think it will work, because there's no state change at all if you click on the 'about' link while you are right on that state.

Is there any ways to work around this? Thanks

like image 938
TonyGW Avatar asked Sep 24 '15 19:09

TonyGW


2 Answers

There is an option attribute called ui-sref-opts that comes with the UI Router. I faced the same problem and it solved it.

Eg: <a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>

Docs URL : UI Router DOcs

like image 82
Siv Avatar answered Oct 08 '22 09:10

Siv


You're right, I can't get any state change events to fire either once already in that state. Until, and if that functionality becomes available to use through that api someday, here's a semi-hacky solution for this. We can just leverage ng-click and use some silly logic to appease QA (in your case). Also, I don't know your controller implementation, so I placed my suggestion on $rootScope in .run in this example for simplicity and visibility, but integrate accordingly if you choose to do so. Observe the following example...

<a ui-sref="about" ng-click="sillyQA()">About</a>

.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScope.sillyQA = function() {
        if($state.current.name === 'about') {
            $state.go('about', {}, { reload: true });
        }
    }

    // -- just to see our about => about state 'change'
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
        console.log('toState:   ' + toState.name );
        console.log('fromState: ' + (fromState.name || 'Just got there! click again!'));
    })
}]);

JSFiddle Link - demo

like image 7
scniro Avatar answered Oct 08 '22 10:10

scniro