2014-05-08 25 views
2

是否可以在Angular应用程序中对模型进行反思/反思,您可以在其中更改范围并遍历它?像batarang这样的东西有但是可以改变这些值。模型自省/反思

如果不是,它是否可以猴子补丁角码(通过在页面上包括另一个脚本),这将使它possilbe?

+0

有项目https://github.com/rev087/ng-inspector,展示了应用的范围,它有一个计划展开/折叠并编辑范围。 – jcubic

回答

2

1.访问/ Modyfing范围属性

角的$scope对象是普通老式JS对象,所以大公可以操纵的标准方式。
例如someScope.someProp检索属性的值,而someScope.someProp = someValue设置属性的值。


2.让角知道

修改对象的属性是一两件事 - 让角认识的改变是另一回事。
角度不会知道我们的修改,直到它运行$digest周期。如果我们想立即应用这些更改,我们可以使用someScope.$apply()明确触发$digest周期。


3.获取一个范围

的保持在为了得到与DOM元素相关联的范围的参考,我们需要有相应的DOM节点对象的引用,它包在angular.element并执行其scope()方法。
事情是这样的:

<body class="ng-scope"> 

var someScope = angular.element(document.body).scope(); 

此外,如果我们想访问$rootScope(所有范围的父范围),我们可以用注射器注入$rootScope服务:

<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); 
} 
+0

谢谢,现在我可以为Angular创建模型自省操纵工具。 – jcubic

+0

@jcubic:您可能已经知道了,但Batarang是开源的,所以无论如何它都是一个很好的开始。 – gkalpak

+0

它不允许改变范围,所以我认为它不是我想要的,也需要刷新浏览器才能看到范围,所以我认为它修改了Angular应用程序或Angular本身以便看到模型。也许我只是分叉Batarang并添加可以修改范围的功能。 – jcubic

1

发现的方式,这里是改变角外的范围代码:

var $scope = angular.element($('.section:eq(0)')).scope(); 
$scope.$apply(function() { 
    scope.color = "blue"; 
}); 

angular.element().scope()将返回范围,可以进行调查。不确定如何遍历范围树,但这是一个很好的起点。如果没有范围遍历,则可以遍历DOM并检查该DOM元素是否有新范围。

+0

而不是角度元素,因为MichałDudak在他的回答中写道,你可以使用jQuery'$('。section:eq(0)')。scope();' – jcubic

1

通过调用angular.element()(或$(),如果您还使用jQuery)返回的对象上的scope()方法,您可以获得范围。 angular.element(".foo").scope()。没有直接访问子范围的方法。但是知道与它们关联的新范围的所有元素都有ng-scope类,您可以改为遍历元素树。

$(".foo").find(".ng-scope").each(function() { 
    var scope = $(this).scope(); 
}); 

然而这可有点棘手,因为find()会发现下面.foo所有节点,而不管它们的深度。您可以使用children()来代替它,但它可能不会产生任何结果,因为.foo的直接后代可能不会创建新范围。

+0

很高兴知道你可以使用jquery获取元素,而不是angular.element和使用范围作为插件。但你可以遍历范围 - 阅读@ExpertSystem的答案。 – jcubic

+1

@jcubic:关于你对jQuery的评论:'.scope()'是一个特定于Angular的方法。如果你同时包含jQuery和Angular(jQuery脚本必须在AngularJS之前),那么'angular.element()'是'$()'的别名,所以你可以用前者来完成任何事情。如果jQuery不存在(或者在AngularJS之后加载),那么'angular.element()'“回退”为使用集成的“leight”版本的jQuery(jqLit​​e)。 – gkalpak