AngularJS:$ rootScope.Controller和Service之间的区别

时间:2015-04-24 09:33:08

标签: angularjs angularjs-scope angularjs-service angularjs-controller

我想了解Angularjs的行为。 我正在构建一个Web应用程序,我希望在所有应用程序组件之间共享CurrentUser的信息。为此,我创建了一个绑定到$ rootScope的CurrentUserController。该控制器由user html元素中使用的body指令使用,因此它可以全局访问,并且只创建一次。

app.controller('CurrentUserController', function ($rootScope) 
  {
   // initialization
   $rootScope.userCtrl = self; //<- MAKE IT GLOBAL
   this.islogged=false;
   this.name="";
   var self = this;
   // functions
   this.isLogged = function() 
        { return self.islogged; };

   this.setLoggedIn = function(credentials) 
        { self.islogged = true; }; 

   this.setLoggedOut = function() 
        { self.islogged = false; };                 
  }
);

app.directive('currentUser', function() {
  return {
    controller:'CurrentUserController'
  };
 })

然后是我的html页面

<html>
...
<body current-user> 
...
</body>
</html>

但是我读到Services应该用于在控制器之间共享数据,因为它们是 singleton 。 所以我的问题是: 我的方法是错误的,还是与我使用的服务相同?

此外,我现在可以使用指令ng-switch调用$rootScope.userCtrl函数,如下所示:

<div id="nav-right-side" class="navbar-right" ng-switch on="userCtrl.isLogged()">
            <div ng-switch-when="false">
                <login-button></login-button>
            </div>
        <div ng-switch-when="true">
                <loggedin-button></loggedin-button>
            </div>                      

        </div>

如果我使用服务,我还能做到吗? 谢谢

2 个答案:

答案 0 :(得分:3)

$rootScope确实在所有应用中共享,最好将模型存储到服务中。

为什么要烦扰服务? 因为$digest周期。每次修改监视值时,都会触发摘要。在角度中,默认情况下,摘要是一个循环,从$rootScope向下到其叶子的所有范围。在每个元素上,如果已修改该值,则必须获取以相应地更新视图。这是相当昂贵的,这是为什么角度在大型应用程序上可能会变慢的原因。保持范围尽可能轻便是如何以角度构建复杂的应用程序。这就是为什么在服务中存储东西总是更好的原因,你不会用你可以放在其他地方的数据来污染范围。

话虽这么说,auth很奇怪,因为你想从视图和服务中访问相同的数据。您可以将它存储在$rootScope中,就像Asta所说的那样,但我不认为这与最佳实践是一致的。 这是自以为是的

可以做的是创建一种服务,通过控制器来控制模型并共享它,以便从视图和其他服务/模型中访问它。

<强> Session.js

function Session(){
     var 
       self = this,

       _islogged=false,
       _name = '';
    // functions
    this.isLogged = function() { 
        return self.islogged; 
    };

    this.setLoggedIn = function() { 
         self.islogged = true; 
    }; 

    this.setLoggedOut = function() { 
        self.islogged = false; };                 
    }

    // GetUsername, setUsername ... Whatever you need
}
angular
    .module('app')
    .service('Session', Session);

<强> rootController.js

function rootController(Session){
    // share the Session Service with the $scope
    // this.session is like $scope.session when using the controllerAS syntax.
    this.session = Session;
}

angular
    .module('app')
    .controller('rootController', rootController);

我建议你看一下这些文章:

答案 1 :(得分:0)

您最好使用Service分享数据,如您所述。在您的方法中,您使用Controller的方式并非真正意图。

您可以使用HTMLng-controller致电您的控制器,因此以下内容应该有效。这对于Login视图或logout指令非常有用。

<div ng-controller="userCtrl">
    <div id="nav-right-side" class="navbar-right" ng-switch on="isLogged()">
       <div ng-switch-when="false">
           <login-button></login-button>
       </div>
       <div ng-switch-when="true">
           <loggedin-button></loggedin-button>
       </div>                      
    </div>
</div>

为了让您的会话可在全球范围内使用以供在其他地方使用,您可以使用service,您可以从app初始化该会话。会话数据可以添加到$rootScope,然后您可以从任何视图或控制器中引用它。

<强>服务

angular.module('app').service('session', function($rootScope) {
    $rootScope.sessionData.loggedIn = true
    // extra logic etc..
});

主要应用

angular.run(session)
angular.module('app').run(function(session) {});

然后从视图中引用变量

<div id="nav-right-side" class="navbar-right" ng-switch on="sessionData.isLoggedIn">

注意:使用带有scope变量的对象来帮助避免继承问题的良好做法。