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

时间:2017-01-25 08:19:56

标签: angularjs angularjs-routing angularjs-rootscope

由于Angular team(和几个blogs)建议,我尽量避免在我的应用中使用$rootScope

  

$rootScope存在,但它可以用于邪恶

     

“当然,全球国家很糟糕,你应该谨慎使用$rootScope,   就像你希望用任何语言的全局变量一样。   特别是,不要将它用于代码,只用于数据。如果你很想   在$rootScope上添加一个函数,将它放入一个函数几乎总是更好   可以在需要的地方注入,更容易注入的服务   测试。“ - 来自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

  • 有更优雅的方式来做这种技巧吗?
  • 我的应用程序设计错误是否使用它?
  • 我必须在绝对必要时辞职吗?

告诉我您是否希望我提供更多代码示例。

2 个答案:

答案 0 :(得分:1)

如果您不想在此方案中使用$rootScope ,您可以使用功能强大的resolve 来实现此目的。

由于我看到您正在使用ngRoute模块,因此我创建了Plunker和ngRoute resolve的代码。如果您也需要,我可以为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

答案 1 :(得分:0)

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

实际上,使用$rootScope - 用于全局事件是绝对可以的 - 这是此服务的实际目的。