ฉันจะเข้าถึงตัวแปร $ scope ในคอนโซลของเบราว์เซอร์โดยใช้ AngularJS ได้อย่างไร


1239

ฉันต้องการเข้าถึง$scopeตัวแปรของฉันในคอนโซล JavaScript ของ Chrome ฉันจะทำอย่างไร

ฉันไม่สามารถมองเห็น$scopeหรือชื่อของโมดูลmyappในคอนโซลเป็นตัวแปร


85
สำหรับการแก้ไขข้อบกพร่องฉันมักจะตั้งค่าwindow.MY_SCOPE = $scope;สิ่งแรกในฟังก์ชั่นควบคุมของฉัน
Jason Goemaat

6
หากคุณกำลังพิจารณาการพัฒนา / ทดสอบใน Firefox คุณสามารถใช้AngScopeซึ่งเป็นส่วนขยายขนาดเล็กที่แสดง$scopeวัตถุขององค์ประกอบ DOM ที่เลือกไว้ในตัวตรวจสอบ DOM ของ Firebug
Kos Prov

@JasonGoemaat ทำไมไม่ใช้หน้าต่าง $ scope = $ scope; เพื่อให้คุณสามารถใช้ขอบเขต $ แทน MY_SCOPE - ฉันไม่ได้สังเกตเห็นปัญหาใด ๆ แต่บางทีฉันอาจกังวลเกี่ยวกับความปลอดภัยหรืออะไรบางอย่าง
James Gentes

8
เพียงเพื่อความชัดเจนคนใหม่ที่เป็นมุมอาจสับสนและคิดว่า $ scope นั้นมีอยู่อย่างน่าอัศจรรย์ในคอนโซลหากเพิ่งเห็นว่ามันถูกใช้อย่างนั้น นอกจากนี้หากคุณใช้ขอบเขตในการประกาศคำสั่งและขอบเขต $ ในโค้ดอย่างไม่เหมาะสมคุณจะใช้สิ่งนั้นกับวัตถุหน้าต่างแทนการรับข้อผิดพลาด
Jason Goemaat

คำตอบ:


1759

เลือกองค์ประกอบในแผง HTML ของเครื่องมือสำหรับนักพัฒนาและพิมพ์ในคอนโซล:

angular.element($0).scope()

ในWebKitและ Firefox$0เป็นการอ้างอิงถึงโหนด DOM ที่เลือกในแท็บองค์ประกอบดังนั้นเมื่อทำสิ่งนี้คุณจะได้รับขอบเขต DOM โหนดที่เลือกที่พิมพ์ออกมาในคอนโซล

นอกจากนี้คุณยังสามารถกำหนดเป้าหมายขอบเขตตามรหัสองค์ประกอบเช่น:

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

addons / ส่วนขยาย

มีส่วนขยาย Chrome ที่มีประโยชน์มากซึ่งคุณอาจต้องการดู:

  • Batarang สิ่งนี้ได้รับรอบในขณะที่

  • NG-สารวัตร นี่เป็นรุ่นใหม่ล่าสุดและตามชื่อแนะนำจะช่วยให้คุณตรวจสอบขอบเขตของแอปพลิเคชันของคุณ

เล่นกับ jsFiddle

เมื่อทำงานกับ jsfiddle คุณสามารถเปิดซอในโหมดแสดงโดยเพิ่ม/showที่ส่วนท้ายของ URL เมื่อทำงานเช่นนี้คุณจะสามารถเข้าถึงangularทั่วโลก คุณสามารถลองได้ที่นี่:

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

jQuery Lite

หากคุณโหลด jQuery ก่อน AngularJS 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
โปรดทราบว่าหากคุณปิดใช้งานข้อมูลการดีบักคุณจะไม่ได้รับการกำหนดโดยใช้วิธีนี้ สิ่งนี้มีจุดประสงค์และสามารถป้องกันได้โดย .. . ดีไม่ปิดการใช้งานข้อมูลการแก้ปัญหาใน $ compileProvider
Robba

6
ทางเลือกอื่นสำหรับ angular.element ($ 0) .scope (): คุณสามารถทำ $ ($ 0) .scope ()
user2954463

1
@jaime ควรพูดถึงวิธีเปิดใช้งานการรับขอบเขตจากองค์ประกอบอีกครั้งเมื่อถูกปิดเพื่อประสิทธิภาพ
enorl76

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
เชิงมุมมีชุดย่อยของ jquery เพื่อให้คุณสามารถใช้ไวยากรณ์ในภายหลัง (ถ้ามันถูกต้อง) ฉันไม่แน่ใจว่ามันเป็น
Pizzaiola Gorgonzola

3
ฉันลงเอยด้วยangular.element(document.body).scope()ขอบคุณ!
Alex Sorokoletov


37

นี่เป็นวิธีหนึ่งในการเข้าถึงขอบเขตโดยไม่มี Batarang คุณสามารถทำได้:

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

หรือถ้าคุณต้องการค้นหาขอบเขตของคุณตามชื่อคอนโทรลเลอร์ให้ทำดังนี้

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

หลังจากที่คุณทำการเปลี่ยนแปลงโมเดลของคุณคุณจะต้องใช้การเปลี่ยนแปลงกับ DOM โดยโทร:

scope.$apply();

4
คำตอบนี้มี upvotes มากมายได้อย่างไร คุณไม่ต้องการ jQuery สำหรับสิ่งนี้! angular.elementเป็นวิธีการเลือกองค์ประกอบแล้ว หยุดบอกว่าคุณต้องการ jQuery สำหรับงานง่าย ๆ เช่นเลือกองค์ประกอบตาม id!
Kyeotic

3
ฉันไม่ได้บอกว่าคุณต้องการมัน สิ่งที่ฉันพูดคือถ้าคุณมีมันแล้วคุณสามารถใช้มันได้เช่นนี้
BraveNewMath

4
angular.element สิ่งที่คุณใช้อยู่แล้ว jQuery สำหรับ ในความเป็นจริงถ้า jQuery พร้อมใช้งานangular.elementเป็นนามแฝงสำหรับ jQuery คุณไม่มีความซับซ้อนในรหัสของคุณ angular.element('#selectorId')และangular.element('[ng-controller=myController]')ทำสิ่งเดียวกันโดยมีรหัสน้อยกว่า คุณอาจจะเรียกangular.element('#selectorId'.toString())
Kyeotic

8
@Tyrsius บางทีความคิดเห็นของคุณอาจจะถูกกล่าวหาและโกรธน้อยลงและมีความเป็นมืออาชีพมากกว่านี้ใช่ไหม
Tass

6
@Tass คุณพูดถูกฉันหยาบคายโดยไม่จำเป็น ฉันขอโทษ. ก็เพียงพอที่จะบอกว่าสิ่งเดียวกันกำลังทำสองครั้ง
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-also ก็ใช้งานได้เช่นกันแต่ฉันไม่คิดว่ามันจะทำงานได้ใน jsFiddle ฉันได้รับข้อผิดพลาดนี้ใน jsFiddle ภายใน Chrome:

> 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ไม่ใช่การปฏิบัติทั่วไป
เทา

ขวา. เมื่อได้รับคำตอบเหล่านั้นcontrollerAsไม่ใช่การปฏิบัติทั่วไปมันจึงสับสนสำหรับมือใหม่ที่อาจทำตาม "ตำรา" ที่บอกให้พวกเขาควบคุมนามแฝง แต่ก็ไม่เห็นคุณสมบัติโดยไม่ใช้นามแฝง หลายสิ่งเคลื่อนไหวอย่างรวดเร็วเมื่อสองปีก่อน
Michael Blackburn

8

ฉันยอมรับสิ่งที่ดีที่สุดคือ Batarang ด้วย$scopeหลังจากเลือกวัตถุ (เหมือนกับ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 และอื่น ๆ

นี่คือการอ้างอิง Command Line API สำหรับ Firebugที่แสดงรายการการอ้างอิง

$($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

ขณะนี้รายการ $ 0 ถูกเลือกในตัวตรวจสอบ DOM ของ chrome $ 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 ที่จะติดตั้งเช่นกัน แต่ทำงานได้อย่างสมบูรณ์แบบสำหรับสภาพแวดล้อม dev มันจะตรวจสอบแต่ละองค์ประกอบเพื่อรับอินสแตนซ์ของขอบเขตจากนั้นส่งคืนพวกเขาที่มีเลเบลด้วยชื่อตัวควบคุม มันยังเอาคุณสมบัติเริ่มต้นด้วย $ ซึ่งเป็นสิ่งที่ 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

ในเชิงมุมเราได้รับองค์ประกอบ jquery โดย angular.element () .... ช่วยให้ c ...

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

3
เป็นความคิดที่ไม่ดีเพราะคุณต้องแก้ไขซอร์สโค้ด สิ่งนี้น่ารำคาญแม้ว่าจะเป็นรหัสของคุณเองและเป็นไปไม่ได้หากมีบางสิ่งที่ทำงานบนเซิร์ฟเวอร์อื่น แม้ว่าคุณจะสามารถแก้ไขโค้ดได้คุณก็ต้องจำที่จะยกเลิกมัน ดังนั้นในขณะที่ใช้งานได้อาจไม่ใช่วิธีปฏิบัติที่ดีที่สุด
Jim Davis

1
@JimDavis โดยทั่วไปฉันเห็นด้วย แต่มีบางกรณีเมื่อทำสิ่งนี้มีประโยชน์: โดยการแก้ไขแหล่งที่มาชั่วคราวคุณสามารถปล่อยให้โค้ดทำสิ่งที่คุณต้องทำด้วยตนเองซ้ำแล้วซ้ำอีก ดังนั้นเมื่อปัญหารู้สึกยุ่งยากและการดีบักใช้เวลานานฉันจะแก้ไขโค้ด การยกเลิกการเปลี่ยนแปลงนั้นไม่สำคัญด้วยเครื่องมือที่เหมาะสม (git)
maaartinus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.