ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

对于调试,我通常在我的控制器函数中设置 window.MY_SCOPE = $scope; 第一件事。
如果您正在考虑在 Firefox 中进行开发/测试,您还可以使用 AngScope,这是一个小型扩展,可将所选 DOM 元素的 $scope 对象显示到 Firebug 的 DOM Inspector 中。
@JasonGoemaat 为什么不使用 window.$scope = $scope;这样您就可以简单地使用 $scope 而不是 MY_SCOPE - 我没有注意到任何问题,但也许我错过了安全问题或其他什么。
只是为了清楚起见,刚接触 Angular 的人可能会感到困惑,并认为 $scope 如果刚刚看到它以这种方式使用,它就可以在控制台中神奇地使用。此外,如果您随后错误地在指令声明中使用了范围,并且在代码中使用了 $scope,那么您将在窗口对象上使用它,而不是出现错误。

s
str

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

angular.element($0).scope()

WebKit 和 Firefox 中,$0 是对元素选项卡中选定 DOM 节点的引用,因此通过这样做,您可以在控制台中打印出选定的 DOM 节点范围。

您还可以按元素 ID 定位范围,如下所示:

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

插件/扩展

您可能想查看一些非常有用的 Chrome 扩展程序:

巴达朗。这已经有一段时间了。

ng检查员。这是最新的,顾名思义,它允许您检查应用程序的范围。

玩 jsFiddle

使用 jsfiddle 时,您可以通过在 URL 末尾添加 /showshow 模式打开 fiddle。像这样运行时,您可以访问 angular 全局。你可以在这里试试:

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

jQuery 精简版

如果您在 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,有什么想法吗?
@jm- 从 angular.element($0).scope() 开始,它一直有效,直到您尝试调用某些方法。我试过了,由于某种原因,在这个设置中不可能有 HTTP 请求?
请注意,如果您禁用调试信息,则使用此方法将始终未定义。这是有意的,可以通过......好吧,不禁用 $compileProvider 上的调试信息来防止
angular.element($0).scope() 的替代品:你也可以做 $($0).scope()
@jaime 应该提到如何在关闭元素以提高性能时重新启用从元素获取范围。
S
Simon East

为了改进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();

angular 包含 jquery 的一个子集,所以你总是可以使用后面的语法(如果它是正确的),我不确定它是
我最终得到了 angular.element(document.body).scope(),谢谢!
c
chrismarx

如果您已安装 Batarang

然后你可以写:

$scope

当您在 chrome 的元素视图中选择了元素时。参考 - https://github.com/angular/angularjs-batarang#console


B
BraveNewMath

这是一种在没有 Batarang 的情况下进入范围的方法,您可以这样做:

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

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

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

对模型进行更改后,您需要通过调用将更改应用到 DOM:

scope.$apply();

这个答案怎么会有这么多赞?为此,您不需要 jQuery! angular.element 已经是一种元素选择方法。不要再说你需要 jQuery 来完成简单的任务,比如 通过 id 选择元素!
我没说你需要。我要说的是,如果你已经有了它,你可以像这样使用它。
angular.element已经做了您使用 jQuery 做的事情。事实上,如果 jQuery 可用,angular.element 是 jQuery 的一个别名。您不必要地使您的代码复杂化。 angular.element('#selectorId')angular.element('[ng-controller=myController]') 做同样的事情,只是代码更少。您不妨致电 angular.element('#selectorId'.toString())
@Tyrsius,也许你的反馈可能不那么指责和愤怒,更专业一点?
@Tass你是对的,我是不必要的粗鲁。我道歉。说同一件事被做了两次就足够了。
M
Mark Rajcok

在你的控制器的某个地方(通常最后一行是一个好地方),把

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: 角度未定义


M
Michael Blackburn

对其中许多答案的一个警告:如果您为控制器设置别名,则您的范围对象将位于 scope() 返回的对象内的一个对象中。

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


控制器 作为 $scope 的属性进行查看(因此在控制台中),默认命名为 $ctrl,与您是否使用 controllerAs 重命名它无关。我不明白您在现有答案中哪里看到了“警告”。请注意,这里的大多数答案都是在 controllerAs 不是常见做法时提供的。
正确的。当给出这些答案时,controllerAs 并不是常见的做法,因此对于可能一直遵循告诉他们为控制器别名的“食谱”的新手来说,这是令人困惑的,但是在不使用别名的情况下看不到属性。两年前事情进展得很快。
J
James Drinkard

要添加和增强其他答案,请在控制台中输入 $($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,依此类推。

这是列出其引用的 Command Line API reference for Firebug

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

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

查看元素父范围:

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

你也可以链接这个:

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

您可以查看根范围:

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

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

$($0).isolateScope()

有关更多详细信息和示例,请参阅 Tips and Tricks for Debugging Unfamiliar Angularjs Code


D
Dorian

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

此外,如果您像我一样在 body 元素上有主范围,则 $('body').scope() 可以正常工作。


S
Sandeep

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

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

实际上,我们在开发中比在生产中更频繁地需要 $scope

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


g
geg

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

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

C
Chris Halcrow

您可以首先从要检查的范围内的 DOM 中选择一个元素:

https://i.stack.imgur.com/kuNDl.png

然后您可以通过在控制台中查询以下内容来查看范围对象:

angular.element($0).scope()

您可以查询范围内的任何属性,例如:

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

或者您可以检查附加到范围的控制器:

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

(另一个可行的选择是在您的代码中放置一个断点。如果 $scope 当前位于当前的“普通旧 JavaScript”范围内,那么您可以在控制台中检查 $scope 的值。)


M
Mike

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

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


w
wojtekc

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

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

$0 当前是 chrome DOM 检查器中的选定项。 $1, $2 .. 等等是之前选择的项目。


M
Mo.

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

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

您可以在控制台中使用以下内容:

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

这将为您提供该元素的范围。


我们在这里不需要“document.querySelector”
K
Khachornchit Songsaen

在 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

https://i.stack.imgur.com/a7fib.png


L
Luke Pring

这也需要安装 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;
        }

R
Rizwan

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

angular.element().scope();

例子:

<div id=""></div>


m
mcvkr

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

   window.scope = $scope;

  $scope.today = new Date();

这就是我使用它的方式。

https://i.stack.imgur.com/U1faS.png

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


A
Asqan

只需在范围之外定义一个 JavaScript 变量并将其分配给控制器中的范围:

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

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

它正在工作,我正在使用这种方法。


使用全局变量是一种不好的做法,但我想这在大多数情况下是可以的。毕竟只是为了调试;但是您仍然必须注意不要两次使用相同的变量名。
这是一个坏主意,因为它需要您修改源代码。即使它是您自己的代码,这也很烦人,如果它是在另一台服务器上运行的东西,这是不可能的。即使您可以修改代码,您也必须记住要撤消它。因此,虽然它可能有效,但它不是最佳做法。
@JimDavis总的来说我同意,但是在某些情况下这样做很有用:通过临时修改源代码,您可以让代码执行您必须一次又一次手动执行的操作。所以当问题感觉很棘手并且调试需要很长时间时,我会修改代码。使用正确的工具 (git) 撤销更改是微不足道的。