在我的 AngularJS 应用程序中,我有一个 Session 服务对象,其中包含当前用户、他们的偏好、他们所属的当前公司以及他们正在使用的当前主题等内容。我的应用程序中的许多地方在需要获取这些数据时都引用了 Session 服务。
因为这些变量在服务中,所以我不能使用范围监视来检测更改。因此,我决定使用观察者模式。应用程序中的各个地方,例如其他服务、指令、控制器等,都会向 Session 服务注册自己,并在 Session 发生变化时提供回调来执行。
例如,如果用户更改了他们的主题,使用自定义指令的<style>
元素index.html
将被通知,并且它将为新颜色重新创建所有覆盖的 css 规则。
再比如,每当用户头像更新时,都会通知主菜单栏控制器刷新并重绘头像。像这样的东西。
显然,在各种控制器、指令等使用之前,Session 中的数据必须至少刷新一次。要求会话服务获取其会话数据的自然位置是run
应用程序级模块的块中。这工作得很好,但我认为这也不是最好的地方。
我注意到的一个问题是,当 Firebug 打开时,加载的异步特性会导致排序问题。例如,在<style>
元素上运行的指令将在应用程序的运行块中刷新会话服务之后运行……这意味着按 F5 后主题不会更新,因为回调是在数据初始化后注册的。我必须在这里调用手动刷新以保持同步,但如果我这样做了,它可能会在顺序不同的时候执行两次!这是个大问题。我不认为这个问题只与 Firebug 相关......它可能在任何情况下发生,但 Firebug 似乎总是会导致它,这很糟糕。
回顾一下......这个异步排序很好:
- 主题指令注册回调到 Session
- 菜单栏应用程序控制器向 Session 注册回调
.run
Session.refresh() 在块中调用。
这种异步排序很糟糕:
- 菜单栏应用程序控制器向 Session 注册回调
.run
Session.refresh() 在块中调用。- 主题指令向 Session 注册回调,但由于 Session.refresh() 已经执行,回调没有被执行。
因此,与其使用观察者模式,或者通过run
块刷新会话状态,不如设计服务的最佳方式等等,以便会话数据总是在应用程序的各个其他部分之后(或之前)被刷新需要吗?在执行指令和控制器而不是运行块之前,我是否可以挂钩某种事件?
如果我的方法总体上是合理的,我可以添加什么来真正让它按应有的方式工作?
谢谢!