Bagaimana cara mengakses variabel $ scope di konsol browser menggunakan AngularJS?

1239

Saya ingin mengakses $scopevariabel saya di konsol JavaScript Chrome. Bagaimana aku melakukan itu?

Saya tidak bisa melihat $scopemaupun nama modul saya myappdi konsol sebagai variabel.

murtaza52
sumber
85
Untuk debugging, saya biasanya mengatur window.MY_SCOPE = $scope;hal pertama dalam fungsi pengontrol saya.
Jason Goemaat
6
Jika Anda mempertimbangkan pengembangan / pengujian di Firefox, Anda juga dapat menggunakan AngScope , ekstensi kecil yang menampilkan $scopeobjek elemen DOM yang dipilih ke dalam Inspektur DOM Firebug.
Kos Ams
@JasonGoemaat mengapa tidak menggunakan jendela. $ Scope = $ scope; sehingga Anda bisa menggunakan $ scope daripada MY_SCOPE - Saya belum melihat adanya masalah tapi mungkin saya kehilangan masalah keamanan atau sesuatu.
James Gentes
8
Hanya untuk kejelasan, seseorang yang baru ke angular mungkin menjadi bingung dan berpikir bahwa $ scope tersedia secara ajaib di konsol jika hanya melihatnya digunakan seperti itu. Juga jika Anda kemudian secara keliru menggunakan lingkup dalam deklarasi direktif dan $ lingkup dalam kode misalnya, Anda akan menggunakannya pada objek jendela bukannya mendapatkan kesalahan.
Jason Goemaat

Jawaban:

1759

Pilih elemen di panel HTML alat pengembang dan ketik ini di konsol:

angular.element($0).scope()

Di WebKit dan Firefox, $0adalah referensi ke simpul DOM yang dipilih di tab elemen, jadi dengan melakukan ini Anda mendapatkan cakupan simpul DOM yang dipilih dicetak di konsol.

Anda juga dapat menargetkan ruang lingkup berdasarkan ID elemen, seperti:

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

Addons / Ekstensi

Ada beberapa ekstensi Chrome yang sangat berguna yang mungkin ingin Anda periksa:

  • Batarang . Ini sudah ada untuk sementara waktu.

  • ng-inspektur . Ini adalah yang terbaru, dan seperti namanya, ini memungkinkan Anda untuk memeriksa cakupan aplikasi Anda.

Bermain dengan jsFiddle

Saat bekerja dengan jsfiddle, Anda dapat membuka biola dalam mode pertunjukan dengan menambahkan /showdi akhir URL. Saat berjalan seperti ini, Anda memiliki akses ke angularglobal. Anda dapat mencobanya di sini:

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

jQuery Lite

Jika Anda memuat jQuery sebelum AngularJS, angular.elementdapat dikirimkan pemilih jQuery. Jadi Anda bisa memeriksa ruang lingkup pengontrol dengan

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

Dari sebuah tombol

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

... dan seterusnya.

Anda mungkin sebenarnya ingin menggunakan fungsi global untuk membuatnya lebih mudah:

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

Sekarang kamu bisa melakukan ini

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

Periksa di sini: http://jsfiddle.net/jaimem/DvRaR/1/show/

jaime
sumber
Terima kasih. Ketika saya mencoba menginstal Batarang itu memberitahu saya komputer Anda tidak didukung, saya punya ubuntu, ada ide?
murtaza52
@ jm- pada angular.element($0).scope(), berfungsi sampai Anda mencoba memanggil beberapa metode. Saya mencoba, dan untuk beberapa alasan tidak ada permintaan HTTP yang mungkin dalam pengaturan ini?
krtek
41
Perhatikan bahwa jika Anda menonaktifkan info debug Anda akan selalu tidak terdefinisi menggunakan metode ini. Hal ini dimaksudkan dan dapat dicegah dengan .. yah, tidak menonaktifkan info debug pada $ compileProvider
Robba
6
alternatif untuk angular.element ($ 0) .scope (): Anda juga dapat melakukan $ ($ 0) .scope ()
user2954463
1
@jaime harus menyebutkan cara mengaktifkan kembali mendapatkan lingkup dari suatu elemen ketika dimatikan untuk kinerja.
enorl76
187

Untuk meningkatkan jawaban 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();

Atau jika Anda menggunakan jQuery, ini melakukan hal yang sama ...

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

Cara mudah lain untuk mengakses elemen DOM dari konsol (seperti yang disebutkan jm) adalah mengkliknya di tab 'elemen', dan secara otomatis akan disimpan sebagai $0.

angular.element($0).scope();
Simon Timur
sumber
3
angular berisi subset dari jquery, jadi Anda selalu dapat menggunakan sintaks yang lebih baru (jika itu benar), saya tidak yakin itu
Pizzaiola Gorgonzola
3
Saya berakhir dengan angular.element(document.body).scope(), terima kasih!
Alex Sorokoletov
37

Ini adalah cara mendapatkan ruang lingkup tanpa Batarang, Anda dapat melakukan:

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

Atau jika Anda ingin menemukan ruang lingkup Anda dengan nama pengontrol, lakukan ini:

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

Setelah Anda membuat perubahan pada model Anda, Anda harus menerapkan perubahan pada DOM dengan menelepon:

scope.$apply();
BraveNewMath
sumber
4
Bagaimana jawaban ini memiliki begitu banyak upvotes? Anda tidak perlu jQuery untuk ini! angular.elementsudah menjadi metode pemilihan elemen. Berhentilah mengatakan Anda memerlukan jQuery untuk tugas-tugas sederhana seperti memilih elemen berdasarkan idnya!
Kyeotic
3
Saya tidak mengatakan Anda membutuhkannya. Apa yang saya katakan adalah jika Anda sudah memilikinya di sana Anda dapat menggunakannya seperti ini.
BraveNewMath
4
angular.element sudah melakukan hal yang Anda gunakan untuk jQuery. Bahkan, jika jQuery tersedia angular.elementadalah alias untuk jQuery. Anda tidak perlu mempersulit kode Anda. angular.element('#selectorId')dan angular.element('[ng-controller=myController]')melakukan hal yang sama, hanya dengan kode yang lebih sedikit. Anda mungkin juga memanggilangular.element('#selectorId'.toString())
Kyeotic
8
@ Tysius, mungkin tanggapan Anda bisa kurang menuduh dan marah dan sedikit lebih profesional?
Tass
6
@Tass Anda benar, saya tidak sopan. Saya minta maaf. Cukup mengatakan bahwa hal yang sama dilakukan dua kali.
Kyeotic
31

Di suatu tempat di controller Anda (seringkali baris terakhir adalah tempat yang baik), taruh

console.log($scope);

Jika Anda ingin melihat lingkup internal / implisit, katakan di dalam ng-repeat, sesuatu seperti ini akan berhasil.

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

Kemudian di controller Anda

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

Perhatikan bahwa di atas kita mendefinisikan fungsi showScope () dalam lingkup orangtua, tapi tidak apa-apa ... ruang lingkup anak / batin / implisit dapat mengakses fungsi itu, yang kemudian mencetak ruang lingkup berdasarkan peristiwa tersebut, dan karenanya lingkup yang terkait dengan elemen yang memecat acara tersebut.

Saran @ jm- juga bekerja, tapi saya rasa itu tidak berhasil di dalam jsFiddle. Saya mendapatkan kesalahan ini di jsFiddle di dalam Chrome:

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

Mark Rajcok
sumber
10

Satu peringatan untuk banyak jawaban ini: jika Anda alias controller Anda objek lingkup Anda akan berada di objek dalam objek yang dikembalikan dari scope().

Misalnya, jika direktif pengontrol Anda dibuat seperti itu: <div ng-controller="FormController as frm"> maka untuk mengakses startDateproperti pengontrol Anda, Anda akan meneleponangular.element($0).scope().frm.startDate

Michael Blackburn
sumber
Pengontrol dapat diakses untuk melihat (karenanya untuk menghibur) sebagai properti $scope, dinamai $ctrlsecara default, terlepas dari apakah Anda mengganti nama menggunakan controllerAsatau tidak. Saya tidak mengerti di mana Anda melihat "peringatan" dalam jawaban yang ada. Perhatikan bahwa sebagian besar jawaban di sini diberikan kembali ketika controllerAsbukan praktik umum.
tao
Baik. Ketika jawaban itu diberikan, controllerAsitu bukan praktik umum, jadi membingungkan bagi pemula yang mungkin telah mengikuti "buku masak" yang memberitahu mereka untuk alias controller, tetapi kemudian tidak melihat properti tanpa menggunakan alias. Segalanya bergerak cepat dua tahun lalu.
Michael Blackburn
8

Saya setuju yang terbaik adalah Batarang dengan itu $scopesetelah memilih objek (sama angular.element($0).scope()atau bahkan lebih pendek dengan jQuery: $($0).scope()(favorit saya))

Juga, jika seperti saya Anda memiliki Anda ruang lingkup utama pada bodyelemen, $('body').scope()berfungsi dengan baik.

Dorian
sumber
7

Untuk menambah dan meningkatkan jawaban lain, di konsol, masukkan $($0)untuk mendapatkan elemen. Jika aplikasi Angularjs, versi jQuery lite dimuat secara default.

Jika Anda tidak menggunakan jQuery, Anda dapat menggunakan angular.element ($ 0) seperti pada:

angular.element($0).scope()

Untuk memeriksa apakah Anda memiliki jQuery dan versinya, jalankan perintah ini di konsol:

$.fn.jquery

Jika Anda telah memeriksa suatu elemen, elemen yang saat ini dipilih tersedia melalui referensi API baris perintah $ 0. Firebug dan Chrome memiliki referensi ini.

Namun, alat pengembang Chrome akan menyediakan lima elemen terakhir (atau tumpukan objek) yang dipilih melalui properti bernama $ 0, $ 1, $ 2, $ 3, $ 4 menggunakan referensi ini. Elemen atau objek yang paling baru dipilih dapat dirujuk sebagai $ 0, yang terbaru kedua sebagai $ 1 dan seterusnya.

Berikut ini adalah referensi API Baris Perintah untuk Firebug yang mencantumkan referensi itu.

$($0).scope()akan mengembalikan lingkup yang terkait dengan elemen. Anda dapat melihat propertinya segera.

Beberapa hal lain yang dapat Anda gunakan adalah:

  • Lihat cakupan elemen induk:

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

  • Anda dapat rantai ini juga:

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

  • Anda dapat melihat lingkup root:

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

  • Jika Anda menyoroti arahan dengan ruang lingkup yang terisolasi, Anda dapat melihatnya dengan:

$($0).isolateScope()

Lihat Kiat dan Trik untuk Mendebug Kode Angular yang Tidak Diketahui untuk detail dan contoh lebih lanjut.

James Drinkard
sumber
5

Periksa elemen, lalu gunakan ini di konsol

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

Cukup tetapkan $scopesebagai variabel global. Masalah terpecahkan.

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

Kita sebenarnya membutuhkan $scopelebih sering dalam pengembangan daripada dalam produksi.

Disebutkan oleh @JasonGoemaat tetapi menambahkannya sebagai jawaban yang cocok untuk pertanyaan ini.

Sandeep
sumber
4

Saya telah menggunakan angular.element($(".ng-scope")).scope();di masa lalu dan itu bekerja dengan baik. Hanya bagus jika Anda hanya memiliki satu cakupan aplikasi pada halaman, atau Anda dapat melakukan sesuatu seperti:

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

Mike
sumber
3

Saya biasanya menggunakan fungsi data jQuery () untuk itu:

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

$ 0 saat ini dipilih di inspektur DOM chrome. $ 1, $ 2 .. dan seterusnya adalah item yang dipilih sebelumnya.

wojtekc
sumber
2

Katakanlah Anda ingin mengakses ruang lingkup elemen seperti

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

Anda dapat menggunakan yang berikut ini di konsol:

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

Ini akan memberi Anda ruang lingkup pada elemen itu.

Praym
sumber
1
kita tidak perlu "document.querySelector" di sini
Stepan Suvorov
1

Di konsol 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

Contoh

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

Konsol Chrome masukkan deskripsi gambar di sini

Khachornchit Songsaen
sumber
1

Ini membutuhkan jQuery untuk diinstal juga, tetapi berfungsi dengan baik untuk lingkungan dev. Itu terlihat melalui setiap elemen untuk mendapatkan instance dari lingkup kemudian mengembalikannya diberi label dengan nama pengontrol di sana. Ini juga menghapus properti yang dimulai dengan $ yang biasanya digunakan angularjs untuk konfigurasinya.

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;
        }
Luke Pring
sumber
0

di sudut kita mendapatkan elemen jquery oleh angular.element () .... ayo ...

angular.element().scope();

contoh:

<div id=""></div>

Rizo
sumber
0

Untuk tujuan debugging saja, saya menempatkan ini di awal controller.

   window.scope = $scope;

  $scope.today = new Date();

Dan ini adalah bagaimana saya menggunakannya.

masukkan deskripsi gambar di sini

kemudian hapus ketika saya selesai debugging.

mcvkr
sumber
-1

Letakkan breakpoint dalam kode Anda di suatu tempat yang dekat dengan referensi ke variabel $ scope (sehingga $ scope berada dalam lingkup 'plain old JavaScript' saat ini). Kemudian Anda dapat memeriksa nilai $ scope di konsol.

Chris Halcrow
sumber
-6

Cukup tentukan variabel JavaScript di luar cakupan dan tetapkan ke lingkup Anda di controller Anda:

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

Itu dia! Ini harus bekerja di semua browser (setidaknya diuji di Chrome dan Mozilla).

Ini berfungsi, dan saya menggunakan metode ini.

Asqan
sumber
2
Menggunakan variabel global adalah praktik yang buruk, tapi saya rasa ini tidak masalah dalam banyak kasus. Lagipula itu hanya untuk debugging; Tapi tetap saja Anda harus berhati-hati untuk tidak menggunakan nama variabel yang sama dua kali.
Pedro Affonso
3
Itu ide yang buruk karena mengharuskan Anda untuk mengubah kode sumber. Ini menjengkelkan bahkan jika itu adalah kode Anda sendiri, dan tidak mungkin jika sesuatu berjalan di server lain. Bahkan jika Anda dapat memodifikasi kode, Anda harus ingat untuk membatalkannya. Jadi sementara itu mungkin berhasil, itu bukan praktik terbaik.
Jim Davis,
1
@ JimDavis Secara umum saya setuju, tetapi ada beberapa kasus ketika melakukan ini berguna: Dengan memodifikasi sementara sumber, Anda dapat membiarkan kode melakukan hal-hal yang harus Anda lakukan secara manual berulang kali. Jadi ketika masalahnya terasa rumit dan proses debug akan memakan waktu lama, saya memodifikasi kodenya. Membatalkan perubahan sepele dengan alat yang tepat (git).
maaartinus