Come posso testare un servizio AngularJS dalla console?


395

Ho un servizio come:

angular.module('app').factory('ExampleService', function(){
  this.f1 = function(world){
    return 'Hello '+world;
  }
  return this;
})

Vorrei testarlo dalla console JavaScript e chiamare la funzione f1()del servizio.

Come lo posso fare?

Risposte:


713

TLDR: in una riga il comando che stai cercando:

angular.element(document.body).injector().get('serviceName')

Profonda immersione

AngularJS utilizza Dependency Injection (DI) per iniettare servizi / fabbriche in componenti, direttive e altri servizi. Quindi quello che devi fare per ottenere un servizio è ottenere prima l' iniettore di AngularJS (l'iniettore è responsabile del cablaggio di tutte le dipendenze e della fornitura ai componenti).

Per ottenere l' iniettore della tua app devi prenderlo da un elemento che angolare sta gestendo. Ad esempio se l'app è registrata sull'elemento body che chiamiinjector = angular.element(document.body).injector()

Da quello recuperato injectorpuoi quindi ottenere qualunque servizio ti piacciainjector.get('ServiceName')

Maggiori informazioni su questo in questa risposta: Impossibile recuperare l'iniettore da angolare
E ancora di più qui: chiamare AngularJS dal codice legacy


Un altro trucco utile per ottenere il $scopedi un elemento particolare. Seleziona l'elemento con lo strumento di ispezione DOM degli strumenti per gli sviluppatori ed esegui la seguente riga ( $0è sempre l'elemento selezionato):
angular.element($0).scope()


70
Ho anche dovuto farlo per farlo funzionare. A proposito, angular.element('*[ng-app]').injector()dovrebbe funzionare per tutti i casi.
Francesc Rosas,

4
Se ricevi l'errore "selettori non implementati" durante l'esecuzione di angular.element ('html'), puoi utilizzare la funzione Chrome $ 0. Seleziona l'elemento html, vai alla console ed esegui angular.element ($ 0) .injector ()
Marek

9
documentfunziona anche:angular.element(document).injector().get('serviceName')
Tamlyn,

1
Cordiali saluti, ho dovuto usare document.body su Chrome
Kevin,

5
Cordiali saluti Volevo usare il servizio $ location, ma alla fine ho dovuto avvolgerlo in scope.apply. So che questo è ben documentato, ma mi è sfuggito di mente. In una riga angular.element (document) .scope (). $ Apply (angular.element (document) .injector (). Get ('$ location'). Path ('/ my /
angular

25

Prima di tutto, una versione modificata del tuo servizio.

a)

var app = angular.module('app',[]);

app.factory('ExampleService',function(){
    return {
        f1 : function(world){
            return 'Hello' + world;
        }
    };
});

Questo restituisce un oggetto, niente di nuovo qui.

Ora il modo per ottenerlo dalla console è

b)

var $inj = angular.injector(['app']);
var serv = $inj.get('ExampleService');
serv.f1("World");

c)

Una delle cose che stavi facendo lì prima era supporre che l'app.factory ti restituisse la funzione stessa o una nuova versione di essa. Non è così. Per ottenere un costruttore dovresti farlo

app.factory('ExampleService',function(){
        return function(){
            this.f1 = function(world){
                return 'Hello' + world;
            }
        };
    });

Questo restituisce un costruttore ExampleService sul quale dovrai successivamente eseguire un 'nuovo'.

O in alternativa,

app.service('ExampleService',function(){
            this.f1 = function(world){
                return 'Hello' + world;
            };
    });

Ciò restituisce il nuovo ExampleService () durante l'iniezione.


3
quando lo faccio, var $inj = angular.injector(['app']);la console genera Error: Unknown provider: $filterProvider from appun'app Error: Unknown provider: $controllerProvider from appin un'altra app ...
JustGoscha

@JustGoscha Come è configurata la tua app? cioè Come fa una linea (che sembra) var app = angular.module ('app', []); sembra nella tua app.
Ganaraj,

Non capisco completamente la domanda .. sembra proprio come dici tu angular.module('app',[]);e poi ci sono servizi, controller ecc in diversi file e sono tutti definiti come angular.module('app').factory('FeatureRegistry',function(){//code here});per esempio
JustGoscha

@JustGoscha Ecco cosa ho fatto per testare. Sono andato a docs.angularjs.org/api in Chrome. Ho aperto la console. Digitato il codice nella sezione a della mia risposta e quindi digitato il codice nella sezione b .. Dovresti vedere Hello World .. Puoi provarci?
Ganaraj,

14

@La risposta di JustGoscha è perfetta, ma è molto da digitare quando voglio l'accesso, quindi l'ho aggiunto in fondo alla mia app.js. Quindi tutto ciò che devo digitare è x = getSrv('$http')ottenere il servizio http.

// @if DEBUG
function getSrv(name, element) {
    element = element || '*[ng-app]';
    return angular.element(element).injector().get(name);
}
// @endif

Lo aggiunge all'ambito globale ma solo in modalità debug. L'ho inserito in @if DEBUGmodo da non finire con esso nel codice di produzione. Uso questo metodo per rimuovere il codice di debug dalle build di prouduction.


4

Il framework di iniezione delle dipendenze di Angularjs è responsabile dell'iniezione delle dipendenze del modulo dell'app nei controller. Questo è possibile attraverso il suo iniettore.

Devi prima identificare la ng-app e ottenere l'iniettore associato. La query seguente funziona per trovare la tua ng-app nel DOM e recuperare l'iniettore.

angular.element('*[ng-app]').injector()

In Chrome, tuttavia, puoi scegliere come target ng-app come mostrato di seguito. e usa l' $0hack e il problemaangular.element($0).injector()

Una volta che hai l'iniettore, ottieni qualsiasi servizio di iniezione di dipendenza come di seguito

injector = angular.element($0).injector();
injector.get('$mdToast');

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.