Comment puis-je tester un service AngularJS à partir de la console?

395

J'ai un service comme:

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

Je voudrais le tester depuis la console JavaScript et appeler la fonction f1()du service.

Comment puis je faire ça?

JustGoscha
la source

Réponses:

713

TLDR: Sur une ligne, la commande que vous recherchez:

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

Plongée profonde

AngularJS utilise l' injection de dépendance (DI) pour injecter des services / usines dans vos composants, directives et autres services. Donc, ce que vous devez faire pour obtenir un service est d'obtenir d'abord l' injecteur d'AngularJS (l'injecteur est responsable du câblage de toutes les dépendances et de leur fourniture aux composants).

Pour obtenir l' injecteur de votre application, vous devez le saisir à partir d'un élément angulaire géré. Par exemple, si votre application est enregistrée sur l'élément de corps que vous appelezinjector = angular.element(document.body).injector()

À partir de la récupération, injectorvous pouvez alors obtenir le service que vous souhaitez avecinjector.get('ServiceName')

Plus d'informations à ce sujet dans cette réponse: Impossible de récupérer l'injecteur de angular
Et encore plus ici: Appelez AngularJS à partir du code hérité


Une autre astuce utile pour obtenir $scopeun élément particulier. Sélectionnez l'élément avec l' outil d'inspection DOM de vos outils de développement, puis exécutez la ligne suivante ( $0est toujours l'élément sélectionné):
angular.element($0).scope()

JustGoscha
la source
70
J'ai aussi dû faire ça pour que ça marche. BTW, angular.element('*[ng-app]').injector()devrait fonctionner pour tous les cas.
Francesc Rosas
4
Si vous obtenez une erreur «sélecteurs non implémentés» lors de l'exécution de angular.element («html»), vous pouvez utiliser la fonctionnalité Chrome $ 0. Sélectionnez l'élément html, accédez à la console et exécutez angular.element ($ 0) .injector ()
Marek
9
documentfonctionne également:angular.element(document).injector().get('serviceName')
Tamlyn
1
Pour info je devais utiliser document.body sur chrome
Kevin
5
Pour info, je voulais utiliser le service $ location, mais j'ai finalement dû l'envelopper dans scope.apply. Je sais que c'est bien documenté, mais ça m'a échappé. En une ligne angular.element (document) .scope (). $ Apply (angular.element (document) .injector (). Get ('$ location'). Path ('/ my / angular / url'))
acid_crucifix
25

Tout d'abord, une version modifiée de votre service.

une )

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

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

Cela renvoie un objet, rien de nouveau ici.

Maintenant, le moyen d'obtenir cela à partir de la console est

b)

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

c)

L'une des choses que vous faisiez auparavant était de supposer que l'application.factory vous renvoie la fonction elle-même ou une nouvelle version de celle-ci. Ce qui n'est pas le cas. Pour obtenir un constructeur, vous devez soit faire

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

Cela renvoie un constructeur ExampleService sur lequel vous devrez ensuite faire un «nouveau».

Ou bien,

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

Cela renvoie un nouveau ExampleService () lors de l'injection.

ganaraj
la source
3
quand je le fais var $inj = angular.injector(['app']);alors la console lance une Error: Unknown provider: $filterProvider from appdans une application et Error: Unknown provider: $controllerProvider from appdans une autre application ...
JustGoscha
@JustGoscha Comment est configurée votre application? ie comment fonctionne une ligne (qui ressemble) var app = angular.module ('app', []); ressembler à votre application.
ganaraj
Je ne comprends pas complètement la question .. cela ressemble à ce que vous dites angular.module('app',[]);et puis il y a des services, des contrôleurs, etc. dans différents fichiers et ils sont tous définis comme angular.module('app').factory('FeatureRegistry',function(){//code here});par exemple
JustGoscha
@JustGoscha Voici ce que j'ai fait pour tester. Je suis allé sur docs.angularjs.org/api en chrome. Ouvert la console. Taper le code dans la section a de ma réponse, puis taper le code dans la section b .. Vous devriez voir Hello World .. Pouvez-vous essayer cela?
ganaraj
14

La réponse de @ JustGoscha est parfaite, mais c'est beaucoup à taper quand je veux accéder, alors j'ai ajouté cela au bas de mon app.js. Ensuite, tout ce que je dois taper est x = getSrv('$http')d'obtenir le service http.

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

Il l'ajoute à la portée globale mais uniquement en mode débogage. Je l'ai mis dans le @if DEBUGafin de ne pas le retrouver dans le code de production. J'utilise cette méthode pour supprimer le code de débogage des versions de prouduction.

codeur de bateau
la source
4

Le framework Angularjs Dependency Injection est chargé d'injecter les dépendances de votre module d'application à vos contrôleurs. Cela est possible grâce à son injecteur.

Vous devez d'abord identifier l'application ng et obtenir l'injecteur associé. La requête ci-dessous fonctionne pour trouver votre ng-app dans le DOM et récupérer l'injecteur.

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

Dans Chrome, cependant, vous pouvez pointer vers la cible ng-app comme indiqué ci-dessous. et utiliser le $0hack et le problèmeangular.element($0).injector()

Une fois que vous avez l'injecteur, obtenez tout service injecté de dépendance comme ci-dessous

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

entrez la description de l'image ici

Faiz Mohamed Haneef
la source