我过去曾遇到类似的问题,并考虑了四种可能的方法:
运用 $broadcast
存储设置 $rootScope
观察者模式(就像你在这里一样)
使用$watch
从控制器
以下是我对每个问题的看法:
$广播
在我看到的AngularJS演示中,MiškoHevery谈到了$broadcast
(即事件)的使用和用例.要点$broadcast
是更多的意图是对那些与你正在使用的东西没有紧密结合的事件做出反应,否则一个替代方案可能更可取.关于这个主题,角度维基上的最佳实践指南建议:
仅对原子事件使用.$ broadcast(),. $ emit()和.$ on():在整个应用程序中全局相关的事件(例如用户身份验证或应用程序关闭).
在这里,由于您拥有与任何填充密切相关的设置ng-view
,因此建议使用的替代方案$broadcast
更可取.
$ rootScope
当你提到(并且想要避免)时,这是一个全局状态.尽管这通常是一个简单的选择,但不是我个人喜欢将设置暴露给我的整个应用程序.我个人保留$rootScope
配置设置和'软'变量,如页面标题等.我不会选择使用此选项.
观察者模式
注册针对配置工厂的回调是一种可靠的方法.对于持久性回调,您可以$destroy
在作用域上侦听事件,在remove
Configuration工厂上调用方法以删除回调.这可以被认为是如何$broadcast
使用的一个很好的例子; 控制器关注事件并且必须对其作出反应,但事件本身并不特定于控制器/配置服务共享的数据.
$腕表
通过使用共享服务,可以将其注入任何与设置有关的控制器.现在,对配置的任何更改都会触发您的回调,或许某些视图可能只涉及一个或两个配置设置.$watch
将允许您更轻松地观察仅对这些属性的更改.我无法谈论开销与注册回调,但这对我来说就像是最"有棱有角"的方式.
这是如何使用$watch
以下方法实现的:
var app = angular.module("myApp",[]); app.factory("Configuration",function(){ var data = { settingOne: true, settingTwo: false }; return data; }) app.controller("SettingsCtrl",function($scope, Configuration){ // do something }) app.controller("HomeCtrl",function($scope, Configuration){ // detect any change to configuration settings $scope.$watch(function() { return Configuration; }, function(data) { // do something }, true) // alternatively only react to settingTwo changing $scope.$watch(function() { return Configuration.settingTwo }, function(data) { // do something }) })
请注意,如果您需要稍微复杂的配置工厂,则可以转而使用getter/setter方法并将配置设置保持为私有.然后,在$watch
,您应该观察方法调用而不是属性本身.
更新:
在回答时,我更喜欢$watch
控制器内部的方法.在使用框架开发一段时间之后,我现在尝试$watch
完全不使用控制器,而是在可能的情况下优先在值的更改点或通过杠杆作用直接调用函数ng-change
.
这样做的一个原因是它增加了测试控制器的复杂性,但也许更低效:对于每个$digest
循环角度调用,每个注册的$watch
都将被评估,并且它可能很好地响应对值的变化现有的$watch
.
而不是在这个角度推测缺点和解决方案,这里有一篇关于这个问题的非常好的文章:Angular JS - 你可能不应该在你的控制器中使用$ watch.
我过去曾遇到类似的问题,并考虑了四种可能的方法:
运用 $broadcast
存储设置 $rootScope
观察者模式(就像你在这里一样)
使用$watch
从控制器
以下是我对每个问题的看法:
$广播
在我看到的AngularJS演示中,MiškoHevery谈到了$broadcast
(即事件)的使用和用例.要点$broadcast
是更多的意图是对那些与你正在使用的东西没有紧密结合的事件做出反应,否则一个替代方案可能更可取.关于这个主题,角度维基上的最佳实践指南建议:
仅对原子事件使用.$ broadcast(),. $ emit()和.$ on():在整个应用程序中全局相关的事件(例如用户身份验证或应用程序关闭).
在这里,由于您拥有与任何填充密切相关的设置ng-view
,因此建议使用的替代方案$broadcast
更可取.
$ rootScope
当你提到(并且想要避免)时,这是一个全局状态.尽管这通常是一个简单的选择,但不是我个人喜欢将设置暴露给我的整个应用程序.我个人保留$rootScope
配置设置和'软'变量,如页面标题等.我不会选择使用此选项.
观察者模式
注册针对配置工厂的回调是一种可靠的方法.对于持久性回调,您可以$destroy
在作用域上侦听事件,在remove
Configuration工厂上调用方法以删除回调.这可以被认为是如何$broadcast
使用的一个很好的例子; 控制器关注事件并且必须对其作出反应,但事件本身并不特定于控制器/配置服务共享的数据.
$腕表
通过使用共享服务,可以将其注入任何与设置有关的控制器.现在,对配置的任何更改都会触发您的回调,或许某些视图可能只涉及一个或两个配置设置.$watch
将允许您更轻松地观察仅对这些属性的更改.我无法谈论开销与注册回调,但这对我来说就像是最"有棱有角"的方式.
这是如何使用$watch
以下方法实现的:
var app = angular.module("myApp",[]); app.factory("Configuration",function(){ var data = { settingOne: true, settingTwo: false }; return data; }) app.controller("SettingsCtrl",function($scope, Configuration){ // do something }) app.controller("HomeCtrl",function($scope, Configuration){ // detect any change to configuration settings $scope.$watch(function() { return Configuration; }, function(data) { // do something }, true) // alternatively only react to settingTwo changing $scope.$watch(function() { return Configuration.settingTwo }, function(data) { // do something }) })
请注意,如果您需要稍微复杂的配置工厂,则可以转而使用getter/setter方法并将配置设置保持为私有.然后,在$watch
,您应该观察方法调用而不是属性本身.
更新:
在回答时,我更喜欢$watch
控制器内部的方法.在使用框架开发一段时间之后,我现在尝试$watch
完全不使用控制器,而是在可能的情况下优先在值的更改点或通过杠杆作用直接调用函数ng-change
.
这样做的一个原因是它增加了测试控制器的复杂性,但也许更低效:对于每个$digest
循环角度调用,每个注册的$watch
都将被评估,并且它可能很好地响应对值的变化现有的$watch
.
而不是在这个角度推测缺点和解决方案,这里有一篇关于这个问题的非常好的文章:Angular JS - 你可能不应该在你的控制器中使用$ watch.