AngularJS:$rootScope.控制器和服务之间的区别



我试图理解Angularjs的行为。 我正在构建一个 Web 应用程序,我希望在所有应用程序组件之间共享当前用户的信息。为此,我创建了一个绑定到$rootScope的CurrentUserController。此控制器由bodyhtml 元素中使用的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'
};
})

然后是我的 HTML 页面

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

但是,我读到Services应该用于在控制器之间共享数据,因为它们是单例的。 所以我的问题是: 我的方法是否错误,或者它与我使用的服务等效?

此外,现在我可以利用指令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>

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

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

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

话虽如此,身份验证很奇特,因为您希望从视图和服务访问相同的数据。您可以像 Asta 所说的那样将其存储在$rootScope中,但我认为这与最佳实践不一致。这是固执己见

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

会话.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);

根控制器.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);

我建议你看看这些文章:

  • AngularJs 应用程序中的身份验证技术
  • 全面的 10 000 字角度教程
  • 深入了解控制器作为语法

你最好使用Service来共享你提到的数据。在你的方法中,你以一种不是真正想要的方式使用了Controller

可以使用ng-controllerHTML调用控制器,因此应可以执行以下操作。例如,这对于登录视图或注销指令很有用。

<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>

为了使您的会话在全球范围内可用以在其他地方使用,您可以使用可以从app初始化的service。可以将会话数据添加到$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变量的对象来帮助避免继承问题。

最新更新