Como posso testar um serviço AngularJS no console?

395

Eu tenho um serviço como:

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

Gostaria de testá-lo no console JavaScript e chamar a função f1()do serviço.

Como eu posso fazer isso?

JustGoscha
fonte

Respostas:

713

TLDR: Em uma linha, o comando que você está procurando:

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

Mergulho profundo

O AngularJS usa injeção de dependência (DI) para injetar serviços / fábricas em seus componentes, diretivas e outros serviços. Portanto, o que você precisa fazer para obter um serviço é obter o injetor do AngularJS primeiro (o injetor é responsável por conectar todas as dependências e fornecê-las aos componentes).

Para obter o injetor do seu aplicativo, você precisa pegá-lo de um elemento que o angular está manipulando. Por exemplo, se seu aplicativo estiver registrado no elemento do corpo que você chamainjector = angular.element(document.body).injector()

A partir dos recuperados, injectorvocê pode obter o serviço que desejar cominjector.get('ServiceName')

Mais informações sobre isso nesta resposta: Não é possível recuperar o injetor do angular
E ainda mais aqui: Ligue para o AngularJS a partir do código legado


Outro truque útil para obter o $scopede um elemento específico. Selecione o elemento com a ferramenta de inspeção DOM de suas ferramentas de desenvolvedor e execute a seguinte linha ( $0sempre é o elemento selecionado):
angular.element($0).scope()

JustGoscha
fonte
70
Eu também tive que fazer isso para fazer funcionar. BTW, angular.element('*[ng-app]').injector()deve funcionar para todos os casos.
Francesc Rosas
4
Se você receber 'seletores não implementados' de erro ao executar angular.element ('html'), poderá usar o recurso $ 0 do Chrome. Selecione o elemento html, vá para o console e execute angular.element ($ 0) .injector ()
Marek
9
documenttambém funciona:angular.element(document).injector().get('serviceName')
Tamlyn 13/13
11
FYI eu tive que usar document.body em cromo
Kevin
5
Para sua informação, eu queria usar o serviço $ location, mas eventualmente precisei envolvê-lo no scope.apply. Eu sei que isso está bem documentado, mas isso me escapou da cabeça. Em uma linha angular.element (document) .scope (). $ Apply (angular.element (document) .injector (). Get ('$ location'). Path ('/ my / angular / url'))
acid_crucifix
25

Primeiro de tudo, uma versão modificada do seu serviço.

a )

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

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

Isso retorna um objeto, nada de novo aqui.

Agora, a maneira de obter isso do console é

b)

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

c)

Uma das coisas que você estava fazendo lá anteriormente era assumir que o app.factory retorna a função em si ou uma versão nova dela. O que não é o caso. Para obter um construtor, você teria que fazer

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

Isso retorna um construtor ExampleService no qual você precisará fazer um 'novo'.

Ou alternativamente,

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

Isso retorna novo ExampleService () na injeção.

ganaraj
fonte
3
quando eu faço var $inj = angular.injector(['app']);, em seguida, o console lança uma Error: Unknown provider: $filterProvider from appem um aplicativo e Error: Unknown provider: $controllerProvider from appem outro aplicativo ...
JustGoscha
@JustGoscha Como o seu aplicativo está configurado? ou seja, como é que uma linha (que se parece) var app = angular.module ('app', []); parece no seu aplicativo.
21313 Ganaraj
Eu não estou entendendo completamente a questão .. olha só como você diz angular.module('app',[]);e, em seguida, existem serviços, controladores, etc em arquivos diferentes e todos eles são definidos como angular.module('app').factory('FeatureRegistry',function(){//code here});por exemplo
JustGoscha
@JustGoscha Aqui está o que eu fiz para testar. Eu fui para docs.angularjs.org/api no chrome. Abriu o console. Digite o código na seção a da minha resposta e digite o código na seção b. Você deverá ver Olá, mundo. Você pode tentar isso?
ganaraj
14

A resposta de @ JustGoscha é imediata, mas é muito para digitar quando eu quero acessar, então eu adicionei isso na parte inferior do meu app.js. Então tudo que eu tenho que digitar é x = getSrv('$http')obter o serviço http.

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

Ele o adiciona ao escopo global, mas apenas no modo de depuração. Coloquei dentro do arquivo @if DEBUGpara não acabar com ele no código de produção. Eu uso esse método para remover o código de depuração das compilações prouduction.

boatcoder
fonte
4

A estrutura de injeção de dependência do Angularjs é responsável por injetar as dependências do seu módulo de aplicativo nos controladores. Isso é possível através do seu injetor.

Você precisa primeiro identificar o aplicativo ng e obter o injetor associado. A consulta abaixo funciona para encontrar seu aplicativo ng no DOM e recuperar o injetor.

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

No chrome, no entanto, você pode apontar para o aplicativo ng, conforme mostrado abaixo. e use o $0hack and issueangular.element($0).injector()

Depois de ter o injetor, obtenha qualquer serviço injetado por dependência, conforme abaixo

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

insira a descrição da imagem aqui

Faiz Mohamed Haneef
fonte