在我的AngularJS应用程序中,我有一个Session服务对象,其中包含当前用户,他们的首选项,他们所属的当前公司以及他们正在使用的当前主题等内容。我的应用程序中的许多地方在需要获取此数据时都会引用会话服务。
因为这些变量在服务中,所以我无法使用范围监视来检测更改。所以相反,我决定使用观察者模式。应用程序中的各个位置(例如其他服务,指令,控制器等)将使用会话服务进行注册,并提供在会话更改时执行的回调。
例如,如果用户更改其主题,则会通知使用自定义指令的<style>
中的index.html
元素,并且它将重新创建新颜色的所有重写css规则。
再例如,每当更新用户的化身时,将通知主菜单栏控制器刷新并重绘头像。像这样的东西。
显然,在各种控制器,指令等使用Session之前,Session中的数据必须至少刷新一次。要求Session服务获取其会话数据的自然位置是应用程序级模块的run
块。这很好用,但我认为这也不是最好的地方。
我注意到的一个问题是,当Firebug打开时,加载事物的异步性质会导致排序问题。例如,在<style>
元素上运行的指令将在会话服务在应用程序的运行块中刷新后运行...这意味着在按F5后主题将不会更新,因为回调是在初始化后注册的发生的数据。我必须在这里调用手动刷新以保持同步,但如果我这样做,它可能会在订单不同的时间执行两次!这是个大问题。我不认为这个问题只与Firebug有关......它可能在任何情况下都会发生,但Firebug似乎会导致它一致,这很糟糕。
回顾一下......这种异步排序很好:
.run
块中调用Session.refresh()。这种异步排序很糟糕:
.run
块中调用Session.refresh()。因此,不是使用观察者模式,或通过run
块刷新会话状态,设计服务的最佳方式等等,以便会话数据总是在之后(或者之前)刷新)应用程序的其他各个部分需要它吗?在执行指令和控制器而不是运行块之前,是否存在某种可以挂钩的事件?
如果我的方法通常是合理的,我可以添加什么来真正使它按照应有的方式工作?
谢谢!
答案 0 :(得分:1)
在angular.js中,您有两种使用全局变量的方法:
使用$ rootScope非常简单,因为您只需将其注入任何控制器并更改此范围内的值即可。所有全局变量都有问题! 服务是单身人士(你需要什么)!
我认为在你的情况下你可以使用
$ rootScope
和
$范围。$观看
很棒answer
答案 1 :(得分:0)
有没有理由不能像这样直接访问变量:
app.factory('SessionService', function() {
var items = {
"avatar": "some url"
};
return items;
});
var MainController = [$scope, 'SessionService', function($scope, SessionService){
$scope.session = SessionService;
$scope.modifyAvatar = function(url){
$scope.session.avatar = "some new url";
};
}];
var HeaderController = [$scope, 'SessionService', function($scope, SessionService){
$scope.session = SessionService;
// You probably wouldn't do this, you would just bind
// to {{session.avatar}} in your template
$scope.getAvatar = function(){
return $scope.session.avatar;
};
}];