尝试避免使用 $rootScope 时路由更改事件

Route change events while trying to avoid using $rootScope

根据 Angular team (and severals blogs) 的建议,我尽量避免在我的应用程序中使用 $rootScope

$rootScope exists, but it can be used for evil

"Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested." - from Angular FAQ

但在我的一个应用程序中,我多次使用 $routeChangeStart 等事件 广播事件 使用 $rootScope:

/* Force redirection to home page when a connected user calls login page */
$rootScope.$on("$routeChangeStart", function(event, next, current) {
    if(next.$$route.originalPath == '/login' && Session.isUserConnected()) {
        $location.path("/home");
    }
}

在这些情况下,我找不到避免 $rootScope 的方法。


如果您希望我提供更多代码示例,请告诉我。

如果你不想在这种情况下使用 $rootScope 你可以使用强大的 resolve.

因为我看到您正在使用 ngRoute 模块,所以我创建了 ngRoute 的 Plunker 和代码 resolve.I 如果您需要,可以为 ui-router 创建一个还有。

使用 Resolve 使代码执行得更快,因为它不会经过 DigestCycle

您可以通过注入会话从 Session.isUserConnected() 中获取用户标志。

然后您可以使用该变量来重定向路由。

// Code goes here

angular.module('Test', ['ngRoute'])
.config(function($routeProvider) {
     var user = true;
     //var user = Session.isUserConnected(); You can use your logic here
    $routeProvider
   .when("/login", {
        template: "Login View",
        resolve: {
           
         data: function($q, $timeout,$location) {
             var deferred = $q.defer();
            $timeout(function() {
              
              if (user) {
                $location.path("/home");
                deferred.reject();
              } else {
                deferred.resolve();
              }
            });
    
            return deferred.promise;
            }
        }
    })
     .when("/home", {
        template: "Home View. It is redirected from Login by checking the user condition. Without using the rootscope",
      })
    .otherwise({redirectTo:'/login'});
})

 
  
<!DOCTYPE html>
<html ng-app="Test">
  <head>
    <link rel="stylesheet" href="style.css" />
  </head>
 
  <body>
    <div ng-view></div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
    <script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-route.js"></script> 
  </body>
</html>

这里是主要部分:

data: function($q, $timeout, $location) {
    var deferred = $q.defer();
    $timeout(function() { 
        if (user) {
            $location.path("/home");
            deferred.reject();
        } else {
            deferred.resolve();
        }
    });
    return deferred.promise;
}

HERE IS A WORKING DEMO

你看错了。 首先,这个事件是由 Angular 团队添加的 - 你认为他们建议不要使用它吗?:D 那篇文章是关于你不应该把所有东西都放在 $rootScope 中,这似乎是一个简单的方法初学者。

实际上,使用 $rootScope - 对于全球事件绝对没问题 -- 这就是此服务的实际目的。