2

在我的 AngularJS 应用程序中,我有一个 Session 服务对象,其中包含当前用户、他们的偏好、他们所属的当前公司以及他们正在使用的当前主题等内容。我的应用程序中的许多地方在需要获取这些数据时都引用了 Session 服务。

因为这些变量在服务中,所以我不能使用范围监视来检测更改。因此,我决定使用观察者模式。应用程序中的各个地方,例如其他服务、指令、控制器等,都会向 Session 服务注册自己,并在 Session 发生变化时提供回调来执行。

例如,如果用户更改了他们的主题,使用自定义指令的<style>元素index.html将被通知,并且它将为新颜色重新创建所有覆盖的 css 规则。

再比如,每当用户头像更新时,都会通知主菜单栏控制器刷新并重绘头像。像这样的东西。

显然,在各种控制器、指令等使用之前,Session 中的数据必须至少刷新一次。要求会话服务获取其会话数据的自然位置是run应用程序级模块的块中。这工作得很好,但我认为这也不是最好的地方。

我注意到的一个问题是,当 Firebug 打开时,加载的异步特性会导致排序问题。例如,在<style>元素上运行的指令将在应用程序的运行块中刷新会话服务之后运行……这意味着按 F5 后主题不会更新,因为回调是在数据初始化后注册的。我必须在这里调用手动刷新以保持同步,但如果我这样做了,它可能会在顺序不同的时候执行两次!这是个大问题。我不认为这个问题只与 Firebug 相关......它可能在任何情况下发生,但 Firebug 似乎总是会导致它,这很糟糕。

回顾一下......这个异步排序很好:

  1. 主题指令注册回调到 Session
  2. 菜单栏应用程序控制器向 Session 注册回调
  3. .runSession.refresh() 在块中调用。

这种异步排序很糟糕:

  1. 菜单栏应用程序控制器向 Session 注册回调
  2. .runSession.refresh() 在块中调用。
  3. 主题指令向 Session 注册回调,但由于 Session.refresh() 已经执行,回调没有被执行。

因此,与其使用观察者模式,或者通过run块刷新会话状态,不如设计服务的最佳方式等等,以便会话数据总是在应用程序的各个其他部分之后(或之前)被刷新需要吗?在执行指令和控制器而不是运行块之前,我是否可以挂钩某种事件?

如果我的方法总体上是合理的,我可以添加什么来真正让它按应有的方式工作?

谢谢!

4

2 回答 2

1

在 angular.js 中,您有两种使用全局变量的方式:

  1. 使用 $rootScope
  2. 使用服务

使用 $rootScope 非常简单,因为您可以简单地将其注入任何控制器并更改此范围内的值。所有全局变量都有问题!服务是单例(你需要什么)!

我认为在你的情况下你可以使用

$rootScope

$scope.$watch

很好的答案

于 2014-02-27T05:29:15.173 回答
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;
    };
}];
于 2014-02-27T05:34:45.577 回答