能否在Angular应用程序中内省/反射模型,以便更改作用域并遍历它?类似于Batarang的东西,但允许更改值。
如果不行,是否可以通过包含另一个脚本来猴子补丁Angular代码,从而使其成为可能?
能否在Angular应用程序中内省/反射模型,以便更改作用域并遍历它?类似于Batarang的东西,但允许更改值。
如果不行,是否可以通过包含另一个脚本来猴子补丁Angular代码,从而使其成为可能?
1. 访问/修改作用域属性
Angular中的$scope
对象是普通的JS对象,因此可以按照标准方式进行操作。
例如:someScope.someProp
检索属性的值,而someScope.someProp = someValue
设置属性的值。
2. 通知Angular
修改对象的属性是一回事,让Angular意识到这个变化是另一回事。
只有在运行$digest
周期后,Angular才会知道我们所做的修改。如果我们想立即应用这些更改,我们可以显式地触发$digest
周期,使用someScope.$apply()
方法。
3. 获取作用域
为了获取与DOM元素相关联的作用域引用,我们需要先获取相应的DOM节点对象的引用,然后将其包装在angular.element
中,并执行其scope()
方法。
代码看起来像这样:
<body class="ng-scope">
var someScope = angular.element(document.body).scope();
<html ng-app="myApp">
var injector = angular.element(document.documentElement).injector();
var rootScope = injector.get('$rootScope');
4. 遍历作用域树
一旦我们获得了一个作用域对象,我们可能想要遍历作用域树。每个作用域都有以下属性(以及其他属性):
$parent
:这个作用域的父级作用域(如果有)。$$nextSibling
:这个作用域的下一个兄弟作用域(如果有)。$parent
的作用域)$$childHead
:这个作用域的第一个子作用域(如果有)。为了遍历以someScope
为根的作用域树分支:
var scopes = [someScope];
while (scopes.length) {
var scope = scopes.shift();
console.log(scope);
if (scope.$$nextSibling) { scopes.unshift(scope.$$nextSibling); }
if (scope.$$childHead) { scopes.unshift(scope.$$childHead); }
}
var injector = angular.element(document.body).injector();
var rootScope = injector.get('$rootScope');
var scopes = [rootScope];
while (scopes.length) {
var scope = scopes.shift();
report(scope);
if (scope.$$nextSibling) { scopes.unshift(scope.$$nextSibling); }
if (scope.$$childHead) { scopes.unshift(scope.$$childHead); }
}
function report(scope) {
var str = '' + scope.$id;
while (scope.$parent) {
str = scope.$parent.$id + ' => ' + str;
scope = scope.$parent;
}
console.log(str);
}
$scope
对象。它会在Firebug的DOM检查器中显示它们。从那里,您可以选择对象以在控制台中使用它,编辑属性并调用$apply()
。 - Kos Prov找到了方法,这里有一段可以改变Angular外部作用域的代码:
var $scope = angular.element($('.section:eq(0)')).scope();
$scope.$apply(function() {
scope.color = "blue";
});
angular.element().scope()
会返回作用域,并可进行调查。不确定如何遍历作用域树,但这是一个很好的起点。如果没有作用域遍历,您可以遍历DOM并检查该DOM元素上是否有新的作用域。
$('.section:eq(0)').scope();
,而不是像Michał Dudak所写的angular元素。 - jcubicangular.element()
(或$()
,如果你还使用jQuery)返回的对象上的scope()
方法来获取作用域,例如:angular.element(".foo").scope()
。没有直接访问子作用域的方法。但是,知道所有具有新作用域的元素都具有ng-scope
类,你可以遍历元素树。$(".foo").find(".ng-scope").each(function() {
var scope = $(this).scope();
});
find()
会查找.foo
下面的所有节点,无论它们的深度如何。你可以使用children()
代替,但它可能不会产生任何结果,因为.foo
的直接后代可能不会创建新的作用域。.scope()
是Angular特定的方法。如果同时引入jQuery和Angular(jQuery脚本必须在AngularJS之前),那么angular.element()
就是$()
的别名,因此你可以通过前者做的任何事情也可以用后者来完成。如果没有加载jQuery(或加载在AngularJS之后),那么angular.element()
将“回退”到使用集成的jQuery(jqLite)的“轻量”版本。 - gkalpak