Angular UI Router issue when redirecting to a template after resolve() throws error

99封情书 提交于 2019-12-31 02:23:09

问题


So It took me a very long time to understand this issue and get to a mcve. Here is the case : I'm trying to redirect a user to a login page when he's not authenticated (this is very basic). Here is the code :

HTML :

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.min.js"></script>
    <script src="js/app.js"></script>
</head>
<body ng-app="starter">

<div ui-view></div>

<script id="login.html" type="text/ng-template">
    l
</script>

<script id="welcome.html" type="text/ng-template">
    w
</script>
</body>
</html>

JS :

    angular.module('starter', ['ui.router'])

.run(["$rootScope", "$state", function($rootScope, $state) {
    $rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
        if (error === "nope") {
            $state.go("login");
        }
    });
}])

.config(function($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise('/welcome');

    $stateProvider
        .state('welcome', {
            url: '/welcome',
            templateUrl: 'welcome.html',
            resolve: {
                "auth": ["$q", function($q) {
                    return $q.reject("nope");
                }]
            }
        })

        .state('login', {
            url: '/login',
            templateUrl: 'views/login.html'
        })
});

The "views/login.html" contains just "vl" to see it showing on the screen. So, when the above code is ran, the output is good, but look at the Chrome console :

Now, the crazy part of it, is if you modify the JS and replace

templateUrl: 'views/login.html'

in the login state by simply

templateUrl: 'login.html'

using the ng-template defined in the html, ALL IS GOOD ! So well, I guess using a file as template must trigger some watcher or whatever... Well no, I'm just out of ideas.

Thanks ahead for your help !

[EDIT]

here are two things that could help :

  • There is no error when using ngRoute in place of UI Router
  • There is no error if replacing Angular version with the 1.2.25

So I think it's a bug with UI Router and Angular 1.3. But don't know at all what to do to solve it.


回答1:


You need to call event.preventDefault() before you call $state.go().

See here: http://plnkr.co/edit/eUosIpdN7adJFxfDo3kV?p=preview

The main reason this error is occuring, as you have already identified, is that the template url 'views/login.html' doesn't exsit. You said that when you changed the template url from 'views/login.html' to 'login.html' everything worked, and this makes sense because that template does exist.

The reason you are seeing the infinite digest error is that each time you try to access the welcome state the auth resolver is throwing an error which triggers the $stateChangeError event like you would expect it too. Everything is fine up until the point when it tries to go to the login state. Attempting to transition to the login state fails because the template url 'views/login.html' doesn't exist, and this failure is causing your otherwise redirect to bring you back to the welcome state. You can see at this point that arriving back at the welcome state will restart the whole cycle and cause the infinite digest loop.

Simply ensuring that your template urls are correct should prevent this from happening, as you have already discovered.




回答2:


I have had the same problem and this is how I solved it

.run(function($rootScope, $state) {
        $rootScope.$on('$stateChangeError', function() {
          // Redirect user to our login page
          $state.go('auth.login');
        });
      });

Below I pasted my entire page so you can see how it all works together 'use strict';

angular.module('mean.pdash').config(['$stateProvider',

function($stateProvider) {
  // Check if the user is connected
  var checkLoggedin = function($q, $timeout, $http, $location) {
    // Initialize a new promise
    var deferred = $q.defer();
    $http.get('/loggedin').success(function(user) {
      // Authenticated
      console.log(user);
      if (user !== '0') {
        $timeout(deferred.resolve);
      } else {
        $timeout(deferred.reject);
      }
    });

    return deferred.promise;
  };
  $stateProvider.state('pdash', {
    url: '/',
    templateUrl: 'pdash/views/index.html',
    controller: 'PdashController',
    resolve: {
      checkLoggedin: checkLoggedin
    }
  });
}
])
  .run(function($rootScope, $state) {
    $rootScope.$on('$stateChangeError', function() {
      // Redirect user to our login page
      $state.go('auth.login');
    });
  });


来源:https://stackoverflow.com/questions/27710247/angular-ui-router-issue-when-redirecting-to-a-template-after-resolve-throws-er

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!