Làm cách nào để truy cập biến $ scope trong bảng điều khiển của trình duyệt bằng AngularJS?


1239

Tôi muốn truy cập vào $scopebiến của mình trong bảng điều khiển JavaScript của Chrome. Làm thế nào để làm điều đó?

Tôi không thể thấy $scopetên của mô-đun myapptrong bàn điều khiển là biến.


85
Để gỡ lỗi tôi thường đặt window.MY_SCOPE = $scope;điều đầu tiên trong chức năng điều khiển của mình.
Jason Goemaat

6
Nếu bạn đang xem xét phát triển / thử nghiệm trong Firefox, bạn cũng có thể sử dụng AngScope , một tiện ích mở rộng nhỏ hiển thị $scopecác đối tượng của các thành phần DOM được chọn vào Trình kiểm tra DOM của Fireorms .
Kos Prov

@JasonGoemaat tại sao không sử dụng cửa sổ. $ Scope = $ scope; để bạn chỉ có thể sử dụng $ scope thay vì MY_SCOPE - Tôi chưa nhận thấy bất kỳ vấn đề nào nhưng có lẽ tôi đang thiếu một mối quan tâm bảo mật hoặc một cái gì đó.
James Gentes

8
Để rõ ràng, một người mới đến góc cạnh có thể bị nhầm lẫn và nghĩ rằng phạm vi $ có sẵn trong bảng điều khiển nếu chỉ thấy nó được sử dụng theo cách đó. Ngoài ra, nếu sau đó bạn sử dụng nhầm phạm vi trong một khai báo chỉ thị và ví dụ $ scope trong mã, bạn sẽ sử dụng phạm vi đó trên đối tượng cửa sổ thay vì gặp lỗi.
Jason Goemaat

Câu trả lời:


1759

Chọn một yếu tố trong bảng HTML của các công cụ dành cho nhà phát triển và nhập phần tử này vào bảng điều khiển:

angular.element($0).scope()

Trong WebKit và Firefox, $0là một tham chiếu đến nút DOM đã chọn trong tab phần tử, do đó, bằng cách này, bạn có được phạm vi nút DOM đã chọn được in ra trong bảng điều khiển.

Bạn cũng có thể nhắm mục tiêu phạm vi theo ID phần tử, như vậy:

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

Addons / Tiện ích mở rộng

Có một số tiện ích mở rộng Chrome rất hữu ích mà bạn có thể muốn xem:

  • Batagar . Điều này đã được khoảng một thời gian.

  • ng-thanh tra . Đây là cái mới nhất và như tên cho thấy, nó cho phép bạn kiểm tra phạm vi ứng dụng của mình.

Chơi với jsFiddle

Khi làm việc với jsfiddle, bạn có thể mở fiddle trong chế độ hiển thị bằng cách thêm /showvào cuối URL. Khi chạy như thế này bạn có quyền truy cập vào angulartoàn cầu. Bạn có thể thử nó ở đây:

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

jQuery Lite

Nếu bạn tải jQuery trước AngularJS, angular.elementcó thể được thông qua bộ chọn jQuery. Vì vậy, bạn có thể kiểm tra phạm vi của bộ điều khiển với

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

Của một nút

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

... và như thế.

Bạn thực sự có thể muốn sử dụng một chức năng toàn cầu để làm cho nó dễ dàng hơn:

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

Bây giờ bạn có thể làm điều này

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

Kiểm tra tại đây: http://jsfiddle.net/jaimem/DvRaR/1/show/


Cảm ơn. Khi tôi cố gắng cài đặt Batarang, nó cho tôi biết máy tính của bạn không được hỗ trợ, tôi có Ubuntu không, có ý tưởng nào không?
murtaza52

@ jm- như angular.element($0).scope(), nó hoạt động cho đến khi bạn cố gắng gọi một số phương thức. Tôi đã thử và vì một số lý do không có yêu cầu HTTP nào có thể thực hiện được trong thiết lập này?
krtek

41
Lưu ý rằng nếu bạn vô hiệu hóa thông tin gỡ lỗi, bạn sẽ luôn không xác định được bằng phương pháp này. Điều này được dự định và có thể được ngăn chặn bởi .. .well, không vô hiệu hóa thông tin gỡ lỗi trên $ compileProvider
Robba

6
thay thế cho angular.element ($ 0) .scope (): bạn cũng có thể làm $ ($ 0) .scope ()
user2954463 18/11/15

1
@jaime nên đề cập đến cách bật lại phạm vi nhận từ một thành phần khi nó bị tắt để thực hiện.
enorl76

187

Để cải thiện câu trả lời của 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();

Hoặc nếu bạn đang sử dụng jQuery, thì điều này cũng tương tự ...

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

Một cách dễ dàng khác để truy cập phần tử DOM từ bảng điều khiển (như jm đã đề cập) là nhấp vào phần tử đó trong tab 'phần tử' và nó tự động được lưu trữ dưới dạng $0.

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

3
angular chứa một tập hợp con của jquery, vì vậy bạn luôn có thể sử dụng cú pháp sau (nếu đúng), tôi không chắc chắn đó là
Pizzaiola Gorgonzola

3
Tôi đã kết thúc với angular.element(document.body).scope(), cảm ơn bạn!
Alex Sorokoletov


37

Đây là một cách để có được phạm vi mà không có Batarang, bạn có thể làm:

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

Hoặc nếu bạn muốn tìm phạm vi của mình theo tên của bộ điều khiển, hãy làm điều này:

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

Sau khi bạn thay đổi mô hình của mình, bạn sẽ cần áp dụng các thay đổi cho DOM bằng cách gọi:

scope.$apply();

4
Làm thế nào để câu trả lời này có rất nhiều upvote? Bạn không cần jQuery cho việc này! angular.elementđã là một phương pháp lựa chọn yếu tố. Dừng nói rằng bạn cần jQuery cho các tác vụ đơn giản như chọn một phần tử theo id của nó!
Kyeotic

3
Tôi không nói bạn cần nó. Những gì tôi đang nói là nếu bạn đã có nó ở đó bạn có thể sử dụng nó như thế này.
BraveNewMath

4
angular.element đã làm điều bạn đang sử dụng jQuery cho. Trong thực tế, nếu jQuery có sẵn angular.elementbí danh cho jQuery. Bạn đang làm phức tạp mã của bạn. angular.element('#selectorId')angular.element('[ng-controller=myController]')làm điều tương tự, chỉ với ít mã hơn. Bạn cũng có thể gọiangular.element('#selectorId'.toString())
Kyeotic

8
@Tyrsius, có lẽ phản hồi của bạn có thể ít bị buộc tội và tức giận và chuyên nghiệp hơn một chút?
Tass

6
@Tass Bạn nói đúng, tôi không cần thiết thô lỗ. Tôi xin lỗi. Nó là đủ để nói rằng điều tương tự đang được thực hiện hai lần.
Kyeotic

31

Một nơi nào đó trong bộ điều khiển của bạn (thường là dòng cuối cùng là một nơi tốt), đặt

console.log($scope);

Nếu bạn muốn xem một phạm vi bên trong / ẩn, hãy nói bên trong một lặp lại ng, một cái gì đó như thế này sẽ hoạt động.

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

Sau đó, trong bộ điều khiển của bạn

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

Lưu ý rằng ở trên chúng tôi xác định hàm showScope () trong phạm vi cha, nhưng không sao ... phạm vi con / bên trong / ẩn có thể truy cập vào hàm đó, sau đó in ra phạm vi dựa trên sự kiện và do đó phạm vi được liên kết với yếu tố đã kích hoạt sự kiện này.

Đề xuất của @ jm-cũng hoạt động, nhưng tôi không nghĩ rằng nó hoạt động trong một jsFiddle. Tôi gặp lỗi này trên jsFiddle bên trong Chrome:

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


10

Một lời cảnh báo cho nhiều câu trả lời sau: nếu bạn đặt bí danh cho bộ điều khiển của mình, các đối tượng phạm vi của bạn sẽ nằm trong một đối tượng trong đối tượng được trả về từ đó scope().

Ví dụ: nếu chỉ thị của bộ điều khiển của bạn được tạo như vậy: <div ng-controller="FormController as frm"> thì để truy cập vào một startDatethuộc tính của bộ điều khiển của bạn, bạn sẽ gọiangular.element($0).scope().frm.startDate


Trình điều khiển thể truy cập để xem (do đó là bàn điều khiển) như một thuộc tính của $scope, được đặt tên $ctrltheo mặc định, độc lập với việc bạn có đổi tên nó bằng cách sử dụng controllerAshay không. Tôi không hiểu bạn đã thấy "cảnh báo" ở đâu trong các câu trả lời hiện có. Lưu ý hầu hết các câu trả lời ở đây đã được cung cấp trở lại khi controllerAskhông phải là một thông lệ.
tao

Đúng. Khi những câu trả lời được đưa ra, controllerAskhông phải là thông lệ, vì vậy thật khó hiểu cho những người mới có thể đã theo dõi "sách dạy nấu ăn" đang bảo họ bí danh bộ điều khiển, nhưng sau đó không thấy các thuộc tính mà không sử dụng bí danh. Mọi thứ đã diễn ra nhanh chóng hai năm trước.
Michael Blackburn

8

Tôi đồng ý tốt nhất là Batarang với nó $scopesau khi chọn một đối tượng (nó giống angular.element($0).scope()hoặc thậm chí ngắn hơn với jQuery: $($0).scope()(yêu thích của tôi))

Ngoài ra, nếu như tôi, bạn có bạn phạm vi chính trên bodyphần tử, một $('body').scope()hoạt động tốt.


7

Để thêm và nâng cao các câu trả lời khác, trong bảng điều khiển, hãy nhập $($0)để lấy phần tử. Nếu đó là một ứng dụng Angularjs, một phiên bản lite jQuery được tải theo mặc định.

Nếu bạn không sử dụng jQuery, bạn có thể sử dụng angular.element ($ 0) như trong:

angular.element($0).scope()

Để kiểm tra xem bạn có jQuery và phiên bản không, hãy chạy lệnh này trong bảng điều khiển:

$.fn.jquery

Nếu bạn đã kiểm tra một phần tử, phần tử hiện được chọn có sẵn thông qua tham chiếu API dòng lệnh $ 0. Cả Fireorms và Chrome đều có tài liệu tham khảo này.

Tuy nhiên, các công cụ dành cho nhà phát triển Chrome sẽ cung cấp năm yếu tố cuối cùng (hoặc đối tượng heap) được chọn thông qua các thuộc tính có tên $ 0, $ 1, $ 2, $ 3, $ 4 bằng cách sử dụng các tham chiếu này. Phần tử hoặc đối tượng được chọn gần đây nhất có thể được tham chiếu là $ 0, gần đây thứ hai là $ 1, v.v.

Dưới đây là tham chiếu API dòng lệnh cho Fireorms liệt kê các tham chiếu của nó.

$($0).scope()sẽ trả về phạm vi liên quan đến phần tử. Bạn có thể thấy tài sản của nó ngay lập tức.

Một số thứ khác mà bạn có thể sử dụng là:

  • Xem một phạm vi cha mẹ yếu tố:

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

  • Bạn cũng có thể xâu chuỗi này:

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

  • Bạn có thể nhìn vào phạm vi gốc:

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

  • Nếu bạn đánh dấu một lệnh có phạm vi cô lập, bạn có thể xem nó với:

$($0).isolateScope()

Xem Mẹo và thủ thuật để gỡ lỗi Mã Angularjs không quen thuộc để biết thêm chi tiết và ví dụ.


5

Kiểm tra phần tử, sau đó sử dụng phần tử này trong bảng điều khiển

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

5

Chỉ cần gán $scopenhư một biến toàn cục. Vấn đề được giải quyết.

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

Chúng tôi thực sự cần $scopethường xuyên hơn trong phát triển hơn là trong sản xuất.

Được đề cập bởi @JasonGoemaat nhưng thêm nó vào như một câu trả lời phù hợp cho câu hỏi này.


4

Tôi đã sử dụng angular.element($(".ng-scope")).scope();trong quá khứ và nó hoạt động rất tốt. Chỉ tốt nếu bạn chỉ có một phạm vi ứng dụng trên trang hoặc bạn có thể làm một cái gì đó như:

angular.element($("div[ng-controller=controllerName]")).scope(); hoặc là angular.element(document.getElementsByClassName("ng-scope")).scope();


3

Tôi thường sử dụng hàm jQuery data () cho điều đó:

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

$ 0 hiện đang được chọn trong mục kiểm tra DOM DOM. $ 1, $ 2 .. và vv là những mục được chọn trước đó.


2

Giả sử bạn muốn truy cập phạm vi của phần tử như

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

Bạn có thể sử dụng như sau trong bảng điều khiển:

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

Điều này sẽ cung cấp cho bạn phạm vi tại yếu tố đó.


1
chúng ta không cần "document.querySelector" ở đây
Stepan Suvorov

1

Tại bảng điều khiển của 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

Thí dụ

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

Bảng điều khiển của Chrome nhập mô tả hình ảnh ở đây


1

Điều này đòi hỏi jQuery cũng phải được cài đặt, nhưng hoạt động hoàn hảo cho môi trường dev. Nó xem qua từng phần tử để lấy các thể hiện của phạm vi sau đó trả về chúng được gắn nhãn có tên của bộ điều khiển. Nó cũng loại bỏ bất kỳ thuộc tính nào bắt đầu bằng $, đó là những gì angularjs thường sử dụng cho cấu hình của nó.

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

trong góc, chúng ta có được phần tử jquery bằng angular.element () .... cho phép ...

angular.element().scope();

thí dụ:

<div id=""></div>


0

Để chỉ gỡ lỗi, tôi đặt cái này vào đầu bộ điều khiển.

   window.scope = $scope;

  $scope.today = new Date();

Và đây là cách tôi sử dụng nó.

nhập mô tả hình ảnh ở đây

sau đó xóa nó khi tôi gỡ lỗi xong.


-1

Đặt một điểm dừng trong mã của bạn ở một nơi nào đó gần với tham chiếu đến biến $ scope (để phạm vi $ nằm trong phạm vi 'JavaScript cũ đơn giản' hiện tại). Sau đó, bạn có thể kiểm tra giá trị phạm vi $ trong bảng điều khiển.


-6

Chỉ cần xác định một biến JavaScript bên ngoài phạm vi và gán nó cho phạm vi của bạn trong bộ điều khiển của bạn:

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

Đó là nó! Nó nên hoạt động trong tất cả các trình duyệt (được thử nghiệm ít nhất trong Chrome và Mozilla).

Nó đang hoạt động và tôi đang sử dụng phương pháp này.


2
Sử dụng các biến toàn cục là một thực tiễn xấu, nhưng tôi đoán điều này là ổn trong hầu hết các trường hợp. Rốt cuộc nó chỉ để gỡ lỗi; Nhưng bạn vẫn phải cẩn thận không sử dụng cùng một tên biến hai lần.
Pedro Affonso

3
Đó là một ý tưởng tồi bởi vì nó yêu cầu bạn sửa đổi mã nguồn. Điều này gây khó chịu ngay cả khi đó là mã của riêng bạn và không thể nếu đó là thứ gì đó đang chạy trên máy chủ khác. Ngay cả khi bạn có thể sửa đổi mã, thì bạn phải nhớ hoàn tác nó. Vì vậy, trong khi nó có thể hoạt động, nó không phải là thực hành tốt nhất.
Jim Davis

1
@JimDavis Nói chung tôi đồng ý, nhưng có những trường hợp khi thực hiện việc này rất hữu ích: Bằng cách tạm thời sửa đổi các nguồn, bạn có thể để mã làm những việc bạn phải làm thủ công nhiều lần. Vì vậy, khi vấn đề cảm thấy khó khăn và việc gỡ lỗi sẽ mất nhiều thời gian, tôi sửa đổi mã. Hoàn tác các thay đổi là không đáng kể với công cụ phù hợp (git).
maaartinus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.