stop angular-ui-router navigation until promise is resolved

前端 未结 10 1950
情歌与酒
情歌与酒 2020-12-01 02:44

I want to prevent some flickering that happens when rails devise timeout occurs, but angular doesn\'t know until the next authorization error from a resource.

What h

10条回答
  •  悲哀的现实
    2020-12-01 03:17

    To add to the existing answers here, I had the exact same issue; we were using an event handler on the root scope to listen for $stateChangeStart for my permission handling. Unfortunately this had a nasty side effect of occasionally causing infinite digests (no idea why, the code was not written by me).

    The solution I came up with, which is rather lacking, is to always prevent the transition with event.preventDefault(), then determine whether or not the user is logged in via an asynchronous call. After verifying this, then use $state.go to transition to a new state. The important bit, though, is that you set the notify property on the options in $state.go to false. This will prevent the state transitions from triggering another $stateChangeStart.

     event.preventDefault();
     return authSvc.hasPermissionAsync(toState.data.permission)
        .then(function () {
          // notify: false prevents the event from being rebroadcast, this will prevent us
          // from having an infinite loop
          $state.go(toState, toParams, { notify: false });
        })
        .catch(function () {
          $state.go('login', {}, { notify: false });
        });
    

    This is not very desirable though, but it's necessary for me due to the way that the permissions in this system are loaded; had I used a synchronous hasPermission, the permissions might not have been loaded at the time of the request to the page. :( Maybe we could ask ui-router for a continueTransition method on the event?

    authSvc.hasPermissionAsync(toState.data.permission).then(continueTransition).catch(function() {
      cancelTransition();
      return $state.go('login', {}, { notify: false });
    });
    

提交回复
热议问题