AngularJS:$rootScope.Controller和服务之间的差异

AngularJS:$rootScope.Controller和服务之间的差异,angularjs,angularjs-scope,angularjs-service,angularjs-controller,Angularjs,Angularjs Scope,Angularjs Service,Angularjs Controller,我试图理解Angularjs的行为。 我正在构建一个web应用程序,我希望在所有应用程序组件之间共享当前用户的信息。为此,我创建了一个绑定到$rootScope的CurrentUserController。此控制器由bodyhtml元素中使用的user指令使用,因此它是全局可访问的,并且只创建一次 app.controller('CurrentUserController', function ($rootScope) { // initialization $rootScop

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

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'
  };
 })
如果我使用服务,我还能这样做吗?
谢谢

所有应用程序都共享
$rootScope
,最好将模型存储到服务中

为什么要为服务费心? 因为
$digest
循环。每次修改关注的值时,都会触发摘要。在angular中,默认情况下摘要是一个循环,它从
$rootScope
向下延伸到它的叶子。在每个元素上,必须获取值是否已修改,以相应地更新视图。这是相当昂贵的,这也是为什么angular在大型应用程序中速度较慢的原因。保持作用域尽可能轻是如何以角度构建复杂应用程序的。这就是为什么在服务中存储东西总是更好的原因,您不会因为可以放在其他地方的数据而污染范围

也就是说,auth是独特的,因为您希望从视图和服务访问相同的数据。正如Asta所说,您可以将其存储在
$rootScope
中,但我认为这与最佳实践并不一致这是自以为是的

可以做的是创建一个服务,该服务将容纳您的模型,并通过控制器共享该模型,以便从视图和其他服务/模型访问该模型

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);
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);
rootController.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);
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);
我建议你看看这些文章:


您最好使用
服务
共享您提到的数据。在你的方法中,你使用了一个
控制器
,而不是它真正想要的方式

您可以使用
ng controller
HTML
调用您的控制器,因此类似于以下内容的操作应该可以正常工作。例如,这对于登录视图或注销指令非常有用

<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>
主应用程序

angular.run(session)
angular.module('app').run(function(session) {});
然后从视图中引用变量

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


注意:使用带有
范围
变量的对象有助于避免继承问题,这是一个很好的做法。

但通过这种方式,
userCtrl
仅在该div中可访问。。。。我想用任何我想用的东西是的,好的。我在一个特定的视图上想象这个控制器,因为这就是控制器的用途。在您的情况下,用户逻辑可以位于
服务中
,要实例化它,您可以从主
应用程序中调用它。运行
函数。因此,您可以设置一个
$rootScope
变量来指示他们是否已登录,而不是
isLogged()
。更新我的答案以供在指令之外使用。那么,要在控制器中使用服务,我应该使用
$rootScope.sessionData
,还是应该将服务作为
.controller('controller',[function(session){…})注入
?如果您想调用
服务中的任何函数,则需要将服务注入控制器。如果您只想从
$rootScope
获取sessionData,那么您可以直接引用它。如果您有导致用户注销的操作(例如,从登录/注销控制器的外部操作),则您可以从该服务更新
$rootScope
,也可以使用事件。即使所有控制器共享相同的服务,以这种方式,我必须在每个(比如)需要它的
div
指令中创建
rootController
的新实例。我说的对吗?不,你不应该有太多,除非指令有一个独立的作用域。在angular中,所有子作用域都从其父作用域继承。如果不使用
controllerAs
语法,则必须使用
$scope.parent
访问父作用域。使用控制器as,如果不同的视图是同级的,则可以通过
rootController.session
从视图访问会话对象。您不必多次实例化此实例。将其放在应用程序的根目录下应该足够了,因此,作为最佳实践,我仍然应该使用
body
元素中的控制器作为我的方法,但我应该将行为外部化到服务中。如果您这样做,您将对所有视图使用登录控制器,它只是初始化会话。我认为您最好直接调用服务,这样就避免了额外的控制器层。@Delac是的,这就是解决方法。
<div id="nav-right-side" class="navbar-right" ng-switch on="sessionData.isLoggedIn">