我的应用程序在$ rootScope中初始化一个对象图,如下所示:
var myApp = angular.module('myApp', []); myApp.run(function ($rootScope) { $rootScope.myObject = { value: 1 }; });
…然后使用该对象图中的数据(仅1向绑定),就像这样…
<p>The value is: {{myObject.value}}</p>
这项工作正常,但是如果我随后(在页面渲染完成之后)尝试更新$ rootScope并将原始对象替换为新对象,则将其忽略。我最初以为这是因为AngularJS保留了对原始对象的引用,即使我已经替换了它。
但是,如果将使用方的HTML包装在控制器中,则可以按预期的方式重复更新其范围,并且修改正确地反映在页面中。
myApp.controller('MyController', function ($scope, $timeout) { $scope.myObject = { value: 3 }; $timeout(function() { $scope.myObject = { value: 4 }; $timeout(function () { $scope.myObject = { value: 5 }; }, 1000); }, 1000); });
有什么方法可以通过$ rootScope完成此操作,还是只能在控制器内部完成?另外,是否有更推荐的模式来实现这种操作?具体来说,我需要一种方法来替换AngularJS从AngularJS代码外部使用的完整对象图。
预先感谢您的建议,蒂姆
编辑:如注释中所建议,我尝试在$ apply内执行更改,但这无济于事:
setTimeout(function() { var injector = angular.injector(["ng", "myApp"]); var rootScope = injector.get("$rootScope"); rootScope.$apply(function () { rootScope.myObject = { value: 6 }; }); console.log("rootScope updated"); }, 5000);
除了非常少见的情况或调试目的外,这样做只是BAD的实践(或BAD应用程序设计的一种指示)!
对于非常罕见的情况(或调试),您可以这样进行:
$rootScope
.scope().$root
$rootScope.$apply()
例如:
function badPractice() { var $body = angular.element(document.body); // 1 var $rootScope = $body.scope().$root; // 2 $rootScope.$apply(function () { // 3 $rootScope.someText = 'This is BAD practice :('; }); }
另请参 见此简短演示 。
编辑
Angular 1.3.x引入了一个选项,以禁止将调试信息附加到DOM元素(包括scope)上: $ compileProvider.debugInfoEnabled() 建议在生产中禁用调试信息(出于性能考虑),这意味着方法将不再起作用。
scope
如果你只是想调试活动(生产)情况下,你可以调用 angular.reloadWithDebugInfo() ,这将刷新页面 与 调试信息功能。
或者,您可以使用Plan B($rootScope通过元素的注入器访问):
function badPracticePlanB() { var $body = angular.element(document.body); // 1 var $rootScope = $body.injector().get('$rootScope'); // 2b $rootScope.$apply(function () { // 3 $rootScope.someText = 'This is BAD practice too :('; }); }