【问题标题】:Broadcast rootscope change广播根范围更改
【发布时间】:2014-09-21 04:03:21
【问题描述】:

我正在尝试编写一个脚本来访问根作用域并从开发工具更改变量值。我可以获得范围和根范围,但我的更改没有显示在我的绑定中。但是,如果我使用绑定输入,一切都很好。

例子:

<input ng-model="mode"></input>
<span ng-bind-html="mode"></span>

彼此更新很好,但是

angular.element("body").scope().$root.mode = 'test'

更新控制器但对绑定没有影响。我使用 === 比较了我的原始控制器和我的控制台控制器,它们是相等的。

所以从我阅读的内容来看,我需要广播或发出我已经更改了范围,但是我似乎无法弄清楚要广播什么,或者我是否正确广播。

广播代码尝试:

scope.$apply(function() {root.$emit('change', {mode: 1})})
scope.$apply(function() {root.$emit('stateChangeSuccess', {mode: 1})})
root.$apply(function() {root.$emit('change', {mode: 1})})
root.$apply(function() {root.$emit('stateChangeSuccess', {mode: 1})})

另外应该注意的是,更改输入会更改跨度,但不会更改我的根范围副本。

root.mode = 'console'
type 'input text' in the input
root.mode returns 'console'

【问题讨论】:

  • 从“角度之外”更新值后,您应该只需要运行一个摘要循环。把 angular.element("body").scope().$root.$apply();在你更新之后。这将触发一个摘要循环,并让视图和模型同步。如果您不订阅(通过 scope.$on)它们,则无需 $emit 更改。

标签: angularjs google-chrome-devtools rootscope


【解决方案1】:

我认为事件不可能做到这一点(也许我错了)。不过,还有另一种方法可以从控制台进行更改。

angular.element("body").scope().$root.mode = 'test' 不更新您的绑定的原因是 Angular 不“知道”已经对范围进行了更改。如果您从 Angular 世界“外部”对数据模型进行更新,则需要将更改包装在 $apply() 函数中:

var $rootScope = angular.element("body").scope().$root;
$rootScope.$apply(function() {
  $rootScope.mode = 'hi';
});

仅供参考,从$rooteScope 发送事件时,您需要使用$broadcast 而不是$emit$broadcast 将事件“向下”广播到所有后代范围,而 $emit 将事件“向上”发送到祖先范围。如果您从$rootScope 获得$emit,则没有祖先作用域可以接收事件(尽管$rootScope 可能会?)。

【讨论】:

  • 仍然没有运气,虽然我可能有一个不同的问题,因为再次查看它我应该注意到更改我的输入无法更新 root.mode,而是 root.mode 保存我设置的最后一个值控制台。
  • mode 变量可能不是来自您的 $rootScope,而是为您的控制器创建的后代范围。如果是这种情况,那么对 $rootScope 进行更改将不会产生任何影响,因为 angular 将查看 mode 的后代范围值。阅读范围继承的工作原理可能会有所帮助:code.angularjs.org/1.2.21/docs/api/ng/type/$rootScope.Scope
  • 我的测试一定是有问题或有错字,我刷新并再次运行了您的代码,它工作正常。感谢所有帮助。
【解决方案2】:

如果我理解正确,scope() === $root,否则你在这里做了一些错误的假设。

我认为正在发生的事情是您正在更改根范围的值,但由于原型继承,您的绑定实际上正在使用另一个范围(例如,当您绑定它时,字符串属性实际上是在 scope() 中创建的)。

试试这两个技巧之一:

1) 试试scope.$apply(function(){scope.mode ='test'});

2) $root.mode={name:'test'}; 并绑定到 html 中的 mode.name

请注意,您应该能够在根作用域上使用 $apply 触发 $digest 循环,并且它也应该向下传播到子作用域。 $root.$apply();

【讨论】:

  • 范围是根的后代。我用 === 检查的是根(从控制器创建生成并放入窗口对象)与我使用 angular.element("body").scope().$root 获得的根。跨度>
  • 让我这样说:你究竟是如何使用控制台打印出 的当前值的?我仍然不明白为什么您希望根范围更改传播到子范围,如果处理原始类型(字符串,整数).. scope().mode 应该获得 绑定的实际值反对。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多