Jak uzyskać dostęp do zmiennej $ scope w konsoli przeglądarki za pomocą AngularJS?

1239

Chciałbym uzyskać dostęp do mojej $scopezmiennej w konsoli JavaScript Chrome. Jak mogę to zrobić?

Nie widzę $scopeani nazwy mojego modułu myappw konsoli jako zmiennych.

murtaza52
źródło
85
Do debugowania zwykle ustawiam window.MY_SCOPE = $scope;pierwszą rzecz w funkcji kontrolera.
Jason Goemaat
6
Jeśli zastanawiasz się nad rozwojem / testowaniem w Firefoksie, możesz także użyć AngScope , małego rozszerzenia, które wyświetla $scopeobiekty wybranych elementów DOM w Inspektorze DOM Firebug.
Kos Prov
@JasonGoemaat, dlaczego nie skorzystać z okna. $ Scope = $ scope; abyś mógł po prostu użyć $ scope zamiast MY_SCOPE - nie zauważyłem żadnych problemów, ale być może brakuje mi obaw dotyczących bezpieczeństwa lub czegoś takiego.
James Gentes
8
Dla jasności ktoś nowy w Angular może się pomylić i pomyśleć, że $ scope był magicznie dostępny w konsoli, gdyby tylko zobaczył, że jest używany w ten sposób. Również, jeśli następnie błędnie użyjesz zakresu w deklaracji dyrektywy i $ scope w kodzie, użyjesz go na obiekcie okna zamiast błędu.
Jason Goemaat

Odpowiedzi:

1759

Wybierz element w panelu HTML narzędzi programistycznych i wpisz go w konsoli:

angular.element($0).scope()

W WebKit i Firefox $0jest odniesieniem do wybranego węzła DOM na karcie elementów, więc w ten sposób otrzymujesz wybrany zakres węzła DOM wydrukowany w konsoli.

Możesz także celować w zakres według identyfikatora elementu, na przykład:

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

Dodatki / rozszerzenia

Istnieje kilka bardzo przydatnych rozszerzeń Chrome, które możesz chcieć sprawdzić:

  • Batarang . To już od jakiegoś czasu.

  • inspektor ng . Jest to najnowszy i, jak sama nazwa wskazuje, umożliwia sprawdzenie zakresów aplikacji.

Gra z jsFiddle

Podczas pracy z jsfiddle możesz otworzyć skrzypce w trybie pokazu , dodając /showna końcu adresu URL. Podczas takiego działania masz dostęp do angularglobalnego. Możesz spróbować tutaj:

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

jQuery Lite

Jeśli załadujesz jQuery przed AngularJS, angular.elementmożesz przekazać selektor jQuery. Abyś mógł sprawdzić zakres kontrolera za pomocą

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

Przycisku

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

... i tak dalej.

Możesz faktycznie użyć funkcji globalnej, aby ułatwić:

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

Teraz możesz to zrobić

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

Sprawdź tutaj: http://jsfiddle.net/jaimem/DvRaR/1/show/

jaime
źródło
Dzięki. Kiedy próbuję zainstalować Batarang, mówi mi, że twój komputer nie jest obsługiwany, mam ubuntu, jakieś pomysły?
murtaza52,
@ jm- od dnia angular.element($0).scope()działa, dopóki nie spróbujesz wywołać niektórych metod. Próbowałem iz jakiegoś powodu żadne żądania HTTP nie są możliwe w tej konfiguracji?
krtek
41
Pamiętaj, że jeśli wyłączysz informacje debugowania, zawsze będziesz niezdefiniowany za pomocą tej metody. Jest to zamierzone i można temu zapobiec przez ... cóż, nie wyłączając informacji debugowania w $ compileProvider
Robba
6
alternatywa dla angular.element (0 $) .scope (): można również zrobić $ (0 $) .scope ()
user2954463
1
@jaime powinien wspomnieć o tym, jak ponownie włączyć uzyskiwanie zasięgu z elementu, gdy został wyłączony ze względu na wydajność.
enorl76
187

Aby poprawić odpowiedź 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();

Lub jeśli używasz jQuery, robi to samo ...

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

Innym łatwym sposobem na uzyskanie dostępu do elementu DOM z konsoli (jak wspomniano w jm) jest kliknięcie go w zakładce „elementy” i automatycznie zostanie on zapisany jako $0.

angular.element($0).scope();
Simon East
źródło
3
angular zawiera podzbiór jquery, więc zawsze możesz użyć późniejszej składni (jeśli jest poprawna), nie jestem pewien, czy tak jest
Pizzaiola Gorgonzola
3
Skończyło się angular.element(document.body).scope(), dziękuję!
Alex Sorokoletov,
37

Jest to sposób na uzyskanie zasięgu bez Bataranga, możesz:

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

Lub jeśli chcesz znaleźć zakres według nazwy kontrolera, wykonaj następujące czynności:

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

Po wprowadzeniu zmian w modelu należy zastosować zmiany w modelu DOM, wywołując:

scope.$apply();
BraveNewMath
źródło
4
Jak ta odpowiedź ma tyle głosów poparcia? Nie potrzebujesz do tego jQuery! angular.elementjest już metodą wyboru elementu. Przestań mówić, że potrzebujesz jQuery do prostych zadań, takich jak wybieranie elementu według jego identyfikatora!
Kyeotic,
3
Nie powiedziałem, że potrzebujesz. Mówię, że jeśli już go masz, możesz użyć go w ten sposób.
BraveNewMath
4
angular.element już robi to, do czego używasz jQuery. W rzeczywistości, jeśli jQuery jest dostępny, angular.elementjest to alias dla jQuery. Niepotrzebnie komplikujesz swój kod. angular.element('#selectorId')i angular.element('[ng-controller=myController]')rób to samo, tylko z mniejszym kodem. angular.element('#selectorId'.toString())
Równie
8
@Tyrsius, może twoja opinia może być mniej oskarżycielska i wściekła i nieco bardziej profesjonalna?
Tass
6
@Tass Masz rację, byłem niepotrzebnie niegrzeczny. Przepraszam. Wystarczy powiedzieć, że to samo robi się dwa razy.
Kyeotic
31

Gdzieś w twoim kontrolerze (często ostatnia linia to dobre miejsce)

console.log($scope);

Jeśli chcesz zobaczyć zakres wewnętrzny / niejawny, powiedzmy w powtórzeniu ng, coś takiego będzie działać.

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

Następnie w kontrolerze

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

Zauważ, że powyżej definiujemy funkcję showScope () w zakresie nadrzędnym, ale to dobrze ... zakres potomny / wewnętrzny / niejawny może uzyskać dostęp do tej funkcji, która następnie drukuje zakres na podstawie zdarzenia, a zatem zakres związany z element, który uruchomił zdarzenie.

Sugestia @ jm-także działa, ale nie sądzę, że działa w jsFiddle. Ten błąd pojawia się w jsFiddle w Chrome:

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

Mark Rajcok
źródło
10

Jedno zastrzeżenie do wielu z tych odpowiedzi: jeśli użyjesz aliasu kontrolera, twoje obiekty zakresu będą w obiekcie w zwróconym obiekcie z scope() .

Na przykład, jeśli twoja dyrektywa kontrolera jest tworzona w taki sposób: <div ng-controller="FormController as frm"> to aby uzyskać dostęp do startDatewłaściwości kontrolera, zadzwoniszangular.element($0).scope().frm.startDate

Michael Blackburn
źródło
Kontroler jest dostępny do przeglądania (stąd do konsoli) jako właściwość o $scopenazwie $ctrldomyślnie niezależnie od tego, czy zmienisz jego nazwę za pomocą controllerAsczy nie. Nie rozumiem, gdzie widziałeś „zastrzeżenie” w istniejących odpowiedziach. Należy zauważyć, że większość odpowiedzi tutaj została udzielona, ​​gdy controllerAsnie była to powszechna praktyka.
tao
Dobrze. Gdy udzielono tych odpowiedzi, controllerAsnie było to powszechną praktyką, więc było mylące dla początkujących, którzy mogli śledzić „książkę kucharską”, która mówiła im, aby alias kontrolera, ale potem nie widzieli właściwości bez użycia aliasu. Dwa lata temu wszystko szło szybko.
Michael Blackburn,
8

Zgadzam się, że najlepszy jest Batarang z nim $scopepo wybraniu obiektu (jest taki sam angular.element($0).scope()lub nawet krótszy z jQuery: $($0).scope()(mój ulubiony))

Ponadto, jeśli tak jak ja, masz główny zakres na bodyelemencie, $('body').scope()działa dobrze.

dorycki
źródło
7

Aby dodać i ulepszyć inne odpowiedzi, w konsoli wprowadź, $($0)aby uzyskać element. Jeśli jest to aplikacja Angularjs, domyślnie ładowana jest wersja jQuery lite.

Jeśli nie używasz jQuery, możesz użyć angular.element (0 $) jak w:

angular.element($0).scope()

Aby sprawdzić, czy masz jQuery i wersję, uruchom to polecenie w konsoli:

$.fn.jquery

Jeśli sprawdziłeś element, aktualnie wybrany element jest dostępny za pośrednictwem interfejsu API w wierszu poleceń nr 0. Zarówno Firebug, jak i Chrome mają to odniesienie.

Jednak narzędzia programistyczne Chrome udostępnią pięć ostatnich elementów (lub obiektów sterty) wybranych za pomocą tych właściwości o nazwach 0, 1, 2, 3, 4 USD. Ostatnio wybrany element lub obiekt może być oznaczony jako 0 USD, drugi jako 1 USD i tak dalej.

Oto odniesienie interfejsu API wiersza polecenia dla Firebug, które zawiera listę odniesień.

$($0).scope()zwróci zakres powiązany z elementem. Możesz zobaczyć jego właściwości od razu.

Niektóre inne rzeczy, których możesz użyć to:

  • Wyświetl zakres nadrzędny elementów:

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

  • Możesz to również połączyć:

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

  • Możesz spojrzeć na zakres główny:

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

  • Jeśli zaznaczyłeś dyrektywę o zakresie izolowania, możesz na nią spojrzeć za pomocą:

$($0).isolateScope()

Zobacz Porady i wskazówki dotyczące debugowania nieznanego kodu Angularjs, aby uzyskać więcej szczegółów i przykładów.

James Drinkard
źródło
5

Sprawdź element, a następnie użyj go w konsoli

s = $($0).scope()
// `s` is the scope object if it exists
geg
źródło
5

Po prostu przypisz $scopejako zmienną globalną. Problem rozwiązany.

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

W rzeczywistości potrzebujemy $scopeczęściej w fazie rozwoju niż w produkcji.

Wspomniany już przez @JasonGoemaat, ale dodając go jako odpowiednią odpowiedź na to pytanie.

Sandeep
źródło
4

Używałem angular.element($(".ng-scope")).scope();w przeszłości i działa świetnie. Dobrze, jeśli masz tylko jeden zakres aplikacji na stronie lub możesz zrobić coś takiego:

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

Mikrofon
źródło
3

Zwykle używam do tego funkcji jQuery data ():

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

0 $ jest obecnie zaznaczonym przedmiotem w chrome inspektorze DOM. 1 USD, 2 USD .. i tak dalej to wcześniej wybrane elementy.

wojtekc
źródło
2

Powiedz, że chcesz uzyskać dostęp do zakresu elementu, np

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

W konsoli można użyć następujących opcji:

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

To da ci zakres w tym elemencie.

Praym
źródło
1
nie potrzebujemy tutaj „document.querySelector”
Stepan Suworow
1

W konsoli 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

Przykład

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

Konsola Chrome wprowadź opis zdjęcia tutaj

Khachornchit Songsaen
źródło
1

Wymaga to również zainstalowania jQuery, ale działa idealnie w środowisku deweloperskim. Przegląda każdy element, aby uzyskać wystąpienia zakresów, a następnie zwraca je oznaczone tam nazwami kontrolerów. Usuwa także wszelkie właściwości zaczynające się od $, który jest zwykle używany przez angularjs do konfiguracji.

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
źródło
0

w angular otrzymujemy element jquery przez angular.element () .... pozwala c ...

angular.element().scope();

przykład:

<div id=""></div>

Rizo
źródło
0

Wyłącznie w celu debugowania umieszczam to na początku kontrolera.

   window.scope = $scope;

  $scope.today = new Date();

I tak to wykorzystuję.

wprowadź opis zdjęcia tutaj

następnie usuń go po zakończeniu debugowania.

Mcvkr
źródło
-1

Umieść punkt przerwania w kodzie, gdzieś blisko odniesienia do zmiennej $ scope (tak, aby $ scope był w bieżącym zakresie „zwykłego starego JavaScript”). Następnie możesz sprawdzić wartość $ scope w konsoli.

Chris Halcrow
źródło
-6

Po prostu zdefiniuj zmienną JavaScript poza zakresem i przypisz ją do swojego zakresu w kontrolerze:

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

Otóż ​​to! Powinien działać we wszystkich przeglądarkach (testowany przynajmniej w Chrome i Mozilli).

Działa i używam tej metody.

Asqan
źródło
2
Używanie zmiennych globalnych jest złą praktyką, ale myślę, że w większości przypadków jest to w porządku. W końcu służy tylko do debugowania; Ale nadal musisz uważać, aby nie użyć dwukrotnie tej samej nazwy zmiennej.
Pedro Affonso
3
To zły pomysł, ponieważ wymaga modyfikacji kodu źródłowego. Jest to denerwujące, nawet jeśli jest to Twój własny kod, i niemożliwe, jeśli działa na innym serwerze. Nawet jeśli możesz zmodyfikować kod, musisz pamiętać o jego cofnięciu. Chociaż może to działać, nie jest to najlepsza praktyka.
Jim Davis,
1
@JimDavis Ogólnie zgadzam się, ale zdarzają się przypadki, gdy jest to przydatne: tymczasowo modyfikując źródła, możesz pozwolić kodowi wykonywać czynności, które musisz robić ręcznie od nowa. Więc kiedy problem wydaje się trudny, a debugowanie potrwa długo, modyfikuję kod. Cofanie zmian jest banalne przy użyciu odpowiedniego narzędzia (git).
maaartinus