如何使用AngularJS在浏览器的控制台中访问$ scope变量?


1239

我想$scope在Chrome的JavaScript控制台中访问我的变量。我怎么做?

我既看不到控制台中的$scope模块名称也看不到它的myapp变量。


85
为了调试,我通常window.MY_SCOPE = $scope;在控制器功能中设置第一件事。
詹森·古玛

6
如果您正在考虑在Firefox中进行开发/测试,则还可以使用AngScope,这是一个小的扩展,可$scope将选定DOM元素的对象显示到Firebug的DOM Inspector中。
科斯省

@JasonGoemaat为什么不使用window。$ scope = $ scope; 这样您就可以简单地使用$ scope而不是MY_SCOPE-我没有发现任何问题,但是也许我缺少安全性方面的考虑。
James Gentes 2015年

8
只是为了清楚起见,刚接触angular的人可能会感到困惑,并认为$ scope如果在控制台中神奇地使用了$ scope,就可以使用它。另外,如果您随后错误地在指令声明中使用了作用域,并在代码中错误地使用了$ scope,那么您将在window对象上使用该作用域,而不是得到一个错误。
杰森·古玛

Answers:


1759

在开发人员工具的HTML面板中选择一个元素,然后在控制台中输入以下元素:

angular.element($0).scope()

WebKit和Firefox中,$0是对elements选项卡中所选DOM节点的引用,因此通过执行此操作,可以在控制台中打印出所选DOM节点范围。

您还可以按元素ID定位作用域,如下所示:

angular.element(document.getElementById('yourElementId')).scope()

插件/扩展

您可能需要检查一些非常有用的Chrome扩展程序:

  • Batarang。这已经有一段时间了。

  • ng-inspector。这是最新的,顾名思义,它使您可以检查应用程序的范围。

玩jsFiddle

使用jsfiddle时,您可以通过在URL的末尾添加以显示模式打开小提琴/show。这样运行时,您可以访问angular全局变量。您可以在这里尝试:

http://jsfiddle.net/jaimem/Yatbt/show

jQuery Lite

如果您在AngularJS之前加载jQuery,angular.element则可以传递jQuery选择器。因此,您可以使用以下命令检查控制器的范围

angular.element('[ng-controller=ctrl]').scope()

一个按钮

 angular.element('button:eq(1)').scope()

... 等等。

您实际上可能希望使用全局函数使其变得更容易:

window.SC = function(selector){
    return angular.element(selector).scope();
};

现在您可以执行此操作

SC('button:eq(10)')
SC('button:eq(10)').row   // -> value of scope.row

在这里检查:http : //jsfiddle.net/jaimem/DvRaR/1/show/


谢谢。当我尝试安装Batarang时,它告诉我您的计算机不受支持,我有ubuntu,有什么想法吗?
murtaza52

从@ jm-开始angular.element($0).scope(),在您尝试调用某些方法之前,它一直有效。我尝试过,由于某种原因,在此设置中没有HTTP请求是可能的?
krtek

41
请注意,如果您禁用调试信息,则使用此方法将始终未定义。这是有意的,可以通过... well来避免,不要在$ compileProvider上禁用调试信息
Robba

6
替代angular.element($ 0).scope():您也可以做$($ 0).scope()
2015年

1
@jaime应该提到在为性能而关闭时如何重新启用从元素获取范围。
enorl76 '19

187

为了改善jm的答案...

// Access whole scope
angular.element(myDomElement).scope();

// Access and change variable in scope
angular.element(myDomElement).scope().myVar = 5;
angular.element(myDomElement).scope().myArray.push(newItem);

// Update page to reflect changed variables
angular.element(myDomElement).scope().$apply();

或者,如果您使用的是jQuery,则可以执行相同的操作...

$('#elementId').scope();
$('#elementId').scope().$apply();

从控制台访问DOM元素的另一种简单方法(如jm所述)是在“元素”选项卡中单击它,它会自动存储为$0

angular.element($0).scope();

3
angular包含jquery的子集,因此您始终可以使用更高版本的语法(如果正确),我不确定这是
Pizzaiola Gorgonzola 2014年

3
最后angular.element(document.body).scope(),谢谢!
Alex Sorokoletov '16


37

这是在没有Batarang的情况下进入范围的一种方法,您可以执行以下操作:

var scope = angular.element('#selectorId').scope();

或者,如果您想按控制器名称查找范围,请执行以下操作:

var scope = angular.element('[ng-controller=myController]').scope();

对模型进行更改后,需要通过调用以下命令将更改应用于DOM:

scope.$apply();

4
这个答案怎么会有这么多投票?您不需要jQuery!angular.element已经是一种元素选择方法。别再说您需要jQuery来完成简单的任务,例如通过其ID选择元素!
Kyeotic

3
我不是说你需要它。我的意思是,如果您在那里已经有了它,可以像这样使用它。
BraveNewMath 2015年

4
angular.element 已经完成了您使用jQuery的工作。实际上,如果jQuery可用,则是jQuery angular.element别名。您不必要地使代码复杂化。angular.element('#selectorId')并且angular.element('[ng-controller=myController]')只需更少的代码即可完成相同的操作。您不妨致电angular.element('#selectorId'.toString())
Kyeotic

8
@Tyrsius,也许您的反馈可能会少一些指责和愤怒,而有些专业吗?
塔斯(Tass),2015年

6
@塔斯你说得对,我没礼貌。我道歉。可以说同一件事要做两次。
Kyeotic

31

在控制器中的某个位置(通常最后一行是一个好地方),放在

console.log($scope);

如果要查看内部/隐式作用域,例如在ng-repeat内部,则可以使用类似的方法。

<li ng-repeat="item in items">
   ...
   <a ng-click="showScope($event)">show scope</a>
</li>

然后在您的控制器中

function MyCtrl($scope) {
    ...
    $scope.showScope = function(e) {
        console.log(angular.element(e.srcElement).scope());
    }
}

请注意,上面我们在父作用域中定义了showScope()函数,但这没关系...子/内部/隐式作用域可以访问该函数,然后该函数根据事件打印出作用域,从而与之关联的作用域触发事件的元素。

@ jm-的建议也可以,但是我认为它在jsFiddle内部不起作用。我在Chrome内的jsFiddle上收到此错误:

> angular.element($0).scope()
ReferenceError: angular is not defined


10

请注意其中许多答案:如果您为控制器加上别名,则范围对象将位于所返回对象中的对象中scope()

例如,如果您的控制器指令是这样创建的: <div ng-controller="FormController as frm"> 那么,要访问startDate控制器的属性,您可以调用angular.element($0).scope().frm.startDate


控制器可访问查看(因此到控制台)作为一个属性$scope,名为$ctrl默认情况下,独立的你是否将其重命名使用controllerAs与否。我不明白您在现有答案中在哪里看到“洞穴”。请注意,此处的大多数答案都是在controllerAs不常见的情况下提供的。
tao

对。当给出这些答案时,这controllerAs是不常见的做法,因此对于那些可能一直在遵循“食谱”的新手感到困惑,这些食谱告诉他们为控制器添加别名,但是如果不使用别名就看不到属性。两年前事情发展很快。
Michael Blackburn

8

我同意最好的是$scope选择对象后使用Batarang (它angular.element($0).scope()与jQuery 相同甚至更短:($($0).scope()我最喜欢))

另外,如果像我一样,您将主要范围放在该body元素上,则$('body').scope()效果很好。


7

要添加和增强其他答案,请在控制台中输入$($0)以获取元素。如果是Angularjs应用程序,则默认情况下会加载jQuery lite版本。

如果您不使用jQuery,则可以使用angular.element($ 0),如下所示:

angular.element($0).scope()

要检查您是否有jQuery及其版本,请在控制台中运行以下命令:

$.fn.jquery

如果您已检查元素,则可通过命令行API参考$ 0获得当前选择的元素。Firebug和Chrome都有此参考。

但是,Chrome开发人员工具将使用这些引用通过名称为$ 0,$ 1,$ 2,$ 3,$ 4的属性来选择最后五个元素(或堆对象)。可以将最近选择的元素或对象引用为$ 0,第二个最近的元素或对象引用为$ 1,依此类推。

这是Firebug命令行API参考,列出了它的参考。

$($0).scope()将返回与该元素关联的范围。您可以立即查看其属性。

您可以使用的其他一些东西是:

  • 查看元素的父范围:

$($0).scope().$parent

  • 您也可以将其链接:

$($0).scope().$parent.$parent

  • 您可以查看根范围:

$($0).scope().$root

  • 如果突出显示了具有隔离范围的指令,则可以使用以下命令查看它:

$($0).isolateScope()

有关更多详细信息和示例,请参见调试陌生的Angularjs代码的技巧和窍门


5

检查元素,然后在控制台中使用它

s = $($0).scope()
// `s` is the scope object if it exists

5

只需分配$scope为全局变量即可。问题解决了。

app.controller('myCtrl', ['$scope', '$http', function($scope, $http) {
    window.$scope = $scope;
}

实际上$scope,开发中比生产中需要更多的时间。

@JasonGoemaat已经提到过,但是将其添加为该问题的合适答案。


4

我过去使用angular.element($(".ng-scope")).scope();过,效果很好。只有在页面上只有一个应用程序范围的情况下才可以,或者可以执行以下操作:

angular.element($("div[ng-controller=controllerName]")).scope(); 要么 angular.element(document.getElementsByClassName("ng-scope")).scope();


3

我通常为此使用jQuery data()函数:

$($0).data().$scope

当前在Chrome DOM检查器中选择了$ 0项。$ 1,$ 2 ..等是先前选择的项目。


2

假设您要访问元素的范围,例如

<div ng-controller="hw"></div>

您可以在控制台中使用以下命令:

angular.element(document.querySelector('[ng-controller=hw]')).scope();

这将为您提供该元素的作用域。


1
我们在这里不需要“ document.querySelector”
Stepan Suvorov

1

在Chrome的控制台上:

 1. Select the **Elements** tab
 2. Select the element of your angular's scope. For instance, click on an element <ui-view>, or <div>, or etc.
 3. Type the command **angular.element($0).scope()** with following variable in the angular's scope

angular.element($0).scope().a
angular.element($0).scope().b

Chrome的控制台 在此处输入图片说明


1

这也需要安装jQuery,但是非常适合开发环境。它遍历每个元素以获取范围的实例,然后返回标有控制器名称的实例。它还删除了以$开头的任何属性,这是angularjs通常用于其配置的属性。

let controllers = (extensive = false) => {
            let result = {};
            $('*').each((i, e) => {
                let scope = angular.element(e).scope();
                if(Object.prototype.toString.call(scope) === '[object Object]' && e.hasAttribute('ng-controller')) {
                    let slimScope = {};
                    for(let key in scope) {
                        if(key.indexOf('$') !== 0 && key !== 'constructor' || extensive) {
                            slimScope[key] = scope[key];
                        }
                    }
                    result[$(e).attr('ng-controller')] = slimScope;
                }
            });

            return result;
        }

0

在angular中,我们通过angular.element()获得jquery元素。

angular.element().scope();

例:

<div id=""></div>


0

仅出于调试目的,我将其放在控制器的开头。

   window.scope = $scope;

  $scope.today = new Date();

这就是我的使用方式。

在此处输入图片说明

然后在完成调试后将其删除。


-1

在代码中靠近$ scope变量引用的地方放置一个断点(以便$ scope在当前的“纯JavaScript”范围内)。然后,您可以在控制台中检查$ scope值。


-6

只需在作用域之外定义一个JavaScript变量,然后将其分配给控制器中的作用域即可:

var myScope;
...
app.controller('myController', function ($scope,log) {
     myScope = $scope;
     ...

而已!它应该可以在所有浏览器中使用(至少在Chrome和Mozilla中经过测试)。

它正在工作,并且我正在使用此方法。


2
使用全局变量是一种不好的做法,但是我想在大多数情况下这是可以的。毕竟只是为了调试;但是,您仍然必须注意不要两次使用相同的变量名。
Pedro Affonso 2015年

3
这是一个坏主意,因为它需要您修改源代码。即使这是您自己的代码,也很烦人;如果它是在另一台服务器上运行的话,这是不可能的。即使可以修改代码,也必须记住撤消它。因此,尽管可能有效,但这不是最佳实践。
吉姆·戴维斯

1
@JimDavis一般来说,我同意,但是在某些情况下这样做很有用:通过临时修改源代码,您可以让代码一次又一次地手动执行操作。因此,当问题感到棘手且调试需要花费很长时间时,我将修改代码。使用正确的工具(git)撤消更改是微不足道的。
maaartinus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.