我试图理解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'
};
})
然后是我的 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-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>
为了使您的会话在全球范围内可用以在其他地方使用,您可以使用可以从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
变量的对象来帮助避免继承问题。