Wie greife ich mit AngularJS auf die Variable $ scope in der Browserkonsole zu?

1239

Ich möchte auf meine $scopeVariable in der JavaScript-Konsole von Chrome zugreifen. Wie mache ich das?

Ich kann weder $scopeden Namen meines Moduls myappin der Konsole als Variablen sehen noch.

murtaza52
quelle
85
Zum Debuggen stelle ich normalerweise als window.MY_SCOPE = $scope;erstes meine Controller-Funktion ein.
Jason Goemaat
6
Wenn Sie die Entwicklung / das Testen in Firefox in Betracht ziehen, können Sie auch AngScope verwenden , eine kleine Erweiterung, die $scopeObjekte ausgewählter DOM-Elemente in Firebugs DOM Inspector anzeigt .
Kos Prov
@JasonGoemaat warum nicht Fenster verwenden. $ Scope = $ scope; Damit Sie einfach $ scope anstelle von MY_SCOPE verwenden können - Ich habe keine Probleme bemerkt, aber vielleicht fehlt mir ein Sicherheitsbedenken oder so.
James Gentes
8
Nur aus Gründen der Klarheit könnte jemand, der neu in Angular ist, verwirrt sein und denken, dass $ scope auf magische Weise in der Konsole verfügbar ist, wenn er gerade sieht, dass es auf diese Weise verwendet wird. Auch wenn Sie dann fälschlicherweise scope in einer Direktivendeklaration und $ scope im Code verwenden, würden Sie dies für das Fensterobjekt verwenden, anstatt einen Fehler zu erhalten.
Jason Goemaat

Antworten:

1759

Wählen Sie im HTML-Bereich der Entwicklertools ein Element aus und geben Sie dieses in die Konsole ein:

angular.element($0).scope()

In WebKit und Firefox $0wird auf der Registerkarte "Elemente" auf den ausgewählten DOM-Knoten verwiesen. Auf diese Weise wird der ausgewählte DOM-Knotenbereich in der Konsole ausgedruckt.

Sie können den Bereich auch nach Element-ID ausrichten, z. B.:

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

Addons / Erweiterungen

Es gibt einige sehr nützliche Chrome-Erweiterungen, die Sie möglicherweise ausprobieren möchten:

  • Batarang . Das gibt es schon eine Weile.

  • ng-inspector . Dies ist die neueste Version, mit der Sie, wie der Name schon sagt, die Bereiche Ihrer Anwendung überprüfen können.

Mit jsFiddle spielen

Wenn Sie mit jsfiddle arbeiten, können Sie die Geige im Show- Modus öffnen , indem Sie sie /showam Ende der URL hinzufügen . Wenn Sie so laufen, haben Sie Zugriff auf die angularglobale. Sie können es hier versuchen:

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

jQuery Lite

Wenn Sie jQuery vor AngularJS laden, angular.elementkann ein jQuery-Selektor übergeben werden. So können Sie den Umfang eines Controllers mit überprüfen

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

Von einem Knopf

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

... und so weiter.

Möglicherweise möchten Sie tatsächlich eine globale Funktion verwenden, um dies zu vereinfachen:

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

Jetzt könnten Sie dies tun

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

Überprüfen Sie hier: http://jsfiddle.net/jaimem/DvRaR/1/show/

jaime
quelle
Vielen Dank. Wenn ich versuche, Batarang zu installieren, wird mir mitgeteilt, dass Ihr Computer nicht unterstützt wird. Ich habe Ubuntu. Haben Sie Ideen?
Murtaza52
@ jm- ab angular.element($0).scope()funktioniert es, bis Sie versuchen, einige Methoden aufzurufen. Ich habe es versucht und aus irgendeinem Grund sind in diesem Setup keine HTTP-Anforderungen möglich.
krtek
41
Beachten Sie, dass Sie beim Deaktivieren der Debug-Informationen mit dieser Methode immer undefiniert werden. Dies ist beabsichtigt und kann verhindert werden, indem ... die Debug-Informationen auf dem $ compileProvider
Robba am
6
Alternative zu angle.element ($ 0) .scope (): Sie können auch $ ($ 0) .scope ()
ausführen
1
@jaime sollte erwähnen, wie das Abrufen des Bereichs von einem Element wieder aktiviert werden kann, wenn es für die Leistung deaktiviert wurde.
Enorl76
187

Um die Antwort von jm zu verbessern ...

// 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();

Oder wenn Sie jQuery verwenden, funktioniert dies genauso ...

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

Eine andere einfache Möglichkeit, über die Konsole auf ein DOM-Element zuzugreifen (wie von jm erwähnt), besteht darin, auf der Registerkarte "Elemente" darauf zu klicken, und es wird automatisch als gespeichert $0.

angular.element($0).scope();
Simon East
quelle
3
Angular enthält eine Teilmenge von jquery, so dass Sie immer die spätere Syntax verwenden können (wenn es korrekt ist), ich bin nicht sicher, ob es ist
Pizzaiola Gorgonzola
3
Ich endete mit angular.element(document.body).scope(), danke!
Alex Sorokoletov
37

Dies ist ein Weg, um ohne Batarang zum Ziel zu gelangen. Sie können Folgendes tun:

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

Oder wenn Sie Ihren Bereich anhand des Controllernamens ermitteln möchten, gehen Sie folgendermaßen vor:

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

Nachdem Sie Änderungen an Ihrem Modell vorgenommen haben, müssen Sie die Änderungen auf das DOM anwenden, indem Sie Folgendes aufrufen:

scope.$apply();
BraveNewMath
quelle
4
Wie hat diese Antwort so viele positive Stimmen? Sie brauchen dafür kein jQuery! angular.elementist bereits eine Elementauswahlmethode. Hören Sie auf zu sagen, dass Sie jQuery für einfache Aufgaben wie die Auswahl eines Elements anhand seiner ID
Kyeotic
3
Ich habe nicht gesagt, dass du es brauchst. Was ich sage ist, wenn Sie es bereits dort haben, können Sie es so verwenden.
BraveNewMath
4
angular.element macht bereits das, wofür Sie jQuery verwenden. Wenn jQuery verfügbar angular.elementist, ist dies ein Alias ​​für jQuery. Sie komplizieren Ihren Code unnötig. angular.element('#selectorId')und angular.element('[ng-controller=myController]')machen Sie dasselbe, nur mit weniger Code. Sie können genauso gut anrufenangular.element('#selectorId'.toString())
Kyeotic
8
@ Tyrsius, vielleicht könnte dein Feedback weniger anklagend und wütend und ein bisschen professioneller sein?
Tass
6
@Tass Du hast recht, ich war unnötig unhöflich. Ich entschuldige mich. Es reicht zu sagen, dass dasselbe zweimal gemacht wird.
Kyeotic
31

Irgendwo in Ihrem Controller (oft ist die letzte Zeile ein guter Ort), setzen Sie

console.log($scope);

Wenn Sie einen inneren / impliziten Bereich sehen möchten, z. B. innerhalb einer ng-Wiederholung, funktioniert so etwas.

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

Dann in Ihrem Controller

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

Beachten Sie, dass wir oben die Funktion showScope () im übergeordneten Bereich definieren, aber das ist in Ordnung ... der untergeordnete / innere / implizite Bereich kann auf diese Funktion zugreifen, die dann den Bereich basierend auf dem Ereignis und damit den damit verbundenen Bereich ausgibt das Element, das das Ereignis ausgelöst hat.

Der Vorschlag von @ jm-´ funktioniert auch, aber ich glaube nicht, dass er in einer jsFiddle funktioniert. Ich erhalte diesen Fehler auf jsFiddle in Chrome:

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

Mark Rajcok
quelle
10

Eine Einschränkung für viele dieser Antworten: Wenn Sie Ihren Controller als Alias ​​verwenden, befinden sich Ihre Bereichsobjekte in einem Objekt innerhalb des zurückgegebenen Objekts von scope().

Wenn Ihre Controller-Direktive beispielsweise so erstellt wird: Um <div ng-controller="FormController as frm"> auf eine startDateEigenschaft Ihres Controllers zuzugreifen , würden Sie aufrufenangular.element($0).scope().frm.startDate

Michael Blackburn
quelle
Controller ist zugänglich (daher auf Konsole) zu sehen als eine Eigenschaft $scope, mit dem Namen $ctrlstandardmäßig unabhängig davon , ob Sie benennen Sie es mit controllerAsoder nicht. Ich verstehe nicht, wo Sie in vorhandenen Antworten eine "Einschränkung" gesehen haben . Beachten Sie, dass die meisten Antworten hier zurückgegeben wurden, als dies controllerAsnicht üblich war.
Tao
Recht. Wenn diese Antworten gegeben wurden, controllerAswar dies keine gängige Praxis, daher war es für Neulinge verwirrend, die möglicherweise einem "Kochbuch" gefolgt waren, in dem sie aufgefordert wurden, den Controller als Alias ​​zu verwenden, die Eigenschaften dann jedoch nicht zu sehen, ohne den Alias ​​zu verwenden. Vor zwei Jahren ging es schnell voran.
Michael Blackburn
8

Ich bin damit einverstanden, dass Batarang das Beste ist, nachdem es $scopeein Objekt ausgewählt hat (es ist dasselbe angular.element($0).scope()oder sogar kürzer mit jQuery: $($0).scope()(mein Favorit))

Auch wenn Sie wie ich Ihren Hauptbereich für das bodyElement haben, $('body').scope()funktioniert a einwandfrei.

Dorian
quelle
7

Um die anderen Antworten hinzuzufügen und zu verbessern, geben Sie in der Konsole ein $($0), um das Element abzurufen. Wenn es sich um eine Angularjs-Anwendung handelt, wird standardmäßig eine jQuery Lite-Version geladen.

Wenn Sie jQuery nicht verwenden, können Sie angle.element ($ 0) wie folgt verwenden:

angular.element($0).scope()

Führen Sie diesen Befehl in der Konsole aus, um zu überprüfen, ob Sie über jQuery und die Version verfügen:

$.fn.jquery

Wenn Sie ein Element überprüft haben, ist das aktuell ausgewählte Element über die Befehlszeilen-API-Referenz $ 0 verfügbar. Sowohl Firebug als auch Chrome haben diese Referenz.

Die Chrome-Entwicklertools stellen jedoch die letzten fünf Elemente (oder Heap-Objekte) zur Verfügung, die über die Eigenschaften $ 0, $ 1, $ 2, $ 3, $ 4 unter Verwendung dieser Referenzen ausgewählt wurden. Das zuletzt ausgewählte Element oder Objekt kann als $ 0, das zweitletzte als $ 1 usw. bezeichnet werden.

Hier ist die Befehlszeilen-API-Referenz für Firebug , in der die Referenzen aufgeführt sind.

$($0).scope()gibt den dem Element zugeordneten Bereich zurück. Sie können seine Eigenschaften sofort sehen.

Einige andere Dinge, die Sie verwenden können, sind:

  • Übergeordneten Elementbereich anzeigen:

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

  • Sie können dies auch verketten:

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

  • Sie können sich den Stammbereich ansehen:

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

  • Wenn Sie eine Direktive mit isoliertem Gültigkeitsbereich hervorgehoben haben, können Sie sie mit folgenden Elementen anzeigen:

$($0).isolateScope()

Weitere Details und Beispiele finden Sie unter Tipps und Tricks zum Debuggen von nicht bekanntem Angularjs-Code .

James Drinkard
quelle
5

Untersuchen Sie das Element und verwenden Sie es in der Konsole

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

Einfach $scopeals globale Variable zuweisen . Problem gelöst.

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

Wir brauchen tatsächlich $scopeöfter in der Entwicklung als in der Produktion.

Bereits von @JasonGoemaat erwähnt, aber als geeignete Antwort auf diese Frage hinzugefügt.

Sandeep
quelle
4

Ich habe angular.element($(".ng-scope")).scope();in der Vergangenheit verwendet und es funktioniert großartig. Nur gut, wenn Sie nur einen App-Bereich auf der Seite haben oder Folgendes tun können:

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

Mike
quelle
3

Normalerweise verwende ich dafür die Funktion jQuery data ():

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

Das Element $ 0 ist derzeit im Chrome DOM Inspector als Element ausgewählt. $ 1, $ 2 .. usw. sind zuvor ausgewählte Elemente.

wojtekc
quelle
2

Angenommen, Sie möchten auf den Bereich des Elements wie zugreifen

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

In der Konsole können Sie Folgendes verwenden:

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

Dies gibt Ihnen den Umfang für dieses Element.

Praym
quelle
1
Wir brauchen hier nicht "document.querySelector"
Stepan Suworow
1

An der Chrome-Konsole:

 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

Beispiel

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

Chrome-Konsole Geben Sie hier die Bildbeschreibung ein

Khachornchit Songsaen
quelle
1

Dies erfordert die Installation von jQuery, funktioniert jedoch perfekt für eine Entwicklungsumgebung. Es durchsucht jedes Element, um die Instanzen der Bereiche abzurufen, und gibt sie dann mit den Controller-Namen zurück. Das Entfernen von Eigenschaften beginnt ebenfalls mit einem $, das anglejs im Allgemeinen für seine Konfiguration verwendet.

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
quelle
0

im Winkel erhalten wir jquery element durch angle.element () .... lässt c ...

angular.element().scope();

Beispiel:

<div id=""></div>

Rizo
quelle
0

Nur zum Debuggen habe ich dies an den Start des Controllers gesetzt.

   window.scope = $scope;

  $scope.today = new Date();

Und so benutze ich es.

Geben Sie hier die Bildbeschreibung ein

Löschen Sie es dann, wenn ich mit dem Debuggen fertig bin.

mcvkr
quelle
-1

Setzen Sie einen Haltepunkt in Ihren Code an einer Stelle in der Nähe eines Verweises auf die Variable $ scope (sodass sich der Bereich $ im aktuellen Bereich 'normales altes JavaScript' befindet). Anschließend können Sie den Wert für $ scope in der Konsole überprüfen.

Chris Halcrow
quelle
-6

Definieren Sie einfach eine JavaScript-Variable außerhalb des Bereichs und weisen Sie sie Ihrem Bereich in Ihrem Controller zu:

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

Das ist es! Es sollte in allen Browsern funktionieren (zumindest in Chrome und Mozilla getestet).

Es funktioniert und ich benutze diese Methode.

Asqan
quelle
2
Die Verwendung globaler Variablen ist eine schlechte Praxis, aber ich denke, dies ist in den meisten Fällen in Ordnung. Es ist schließlich nur zum Debuggen; Trotzdem müssen Sie darauf achten, dass Sie denselben Variablennamen nicht zweimal verwenden.
Pedro Affonso
3
Es ist eine schlechte Idee, da Sie den Quellcode ändern müssen. Dies ist ärgerlich, selbst wenn es sich um Ihren eigenen Code handelt, und unmöglich, wenn etwas auf einem anderen Server ausgeführt wird. Selbst wenn Sie den Code ändern können, müssen Sie daran denken, ihn rückgängig zu machen. Es funktioniert zwar, ist aber nicht die beste Vorgehensweise.
Jim Davis
1
@JimDavis Im Allgemeinen stimme ich zu, aber es gibt Fälle, in denen dies nützlich ist: Durch vorübergehendes Ändern der Quellen können Sie den Code die Dinge tun lassen, die Sie immer wieder manuell tun müssten. Wenn sich das Problem schwierig anfühlt und das Debuggen lange dauern wird, ändere ich den Code. Das Rückgängigmachen der Änderungen ist mit dem richtigen Werkzeug (git) trivial.
Maaartinus