Как я могу проверить сервис AngularJS с консоли?

395

У меня есть сервис, как:

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

Я хотел бы проверить это из консоли JavaScript и вызвать функцию f1()сервиса.

Как я могу это сделать?

JustGoscha
источник

Ответы:

713

TLDR: в одной строке команда, которую вы ищете:

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

Глубокое погружение

AngularJS использует Dependency Injection (DI) для внедрения сервисов / фабрик в ваши компоненты, директивы и другие сервисы. Итак, что вам нужно сделать, чтобы получить сервис, так это сначала получить инжектор AngularJS (инжектор отвечает за подключение всех зависимостей и предоставление их компонентам).

Чтобы получить инжектор вашего приложения, вам нужно извлечь его из элемента, который обрабатывает angular. Например, если ваше приложение зарегистрировано в элементе тела, который вы называетеinjector = angular.element(document.body).injector()

Из найденного injectorвы можете получить любую услугу, которая вам нравитсяinjector.get('ServiceName')

Подробнее об этом в этом ответе: Не удается извлечь инжектор из angular
И даже больше здесь: вызов AngularJS из устаревшего кода


Еще один полезный трюк для получения $scopeконкретного элемента. Выберите элемент с помощью инструмента проверки DOM ваших инструментов разработчика, а затем запустите следующую строку ( $0всегда выбранный элемент):
angular.element($0).scope()

JustGoscha
источник
70
Я также должен был сделать это, чтобы это работало. Кстати, angular.element('*[ng-app]').injector()должно работать для всех случаев.
Франческ Росас
4
Если вы получаете ошибку «селекторы не реализованы» при выполнении angular.element («html»), тогда вы можете использовать функцию Chrome $ 0. Выберите элемент html, перейдите в консоль и запустите angular.element ($ 0) .injector ()
Марек
9
documentтакже работает:angular.element(document).injector().get('serviceName')
Тамлин
1
К вашему сведению, я должен был использовать document.body на Chrome
Кевин
5
К вашему сведению, я хотел использовать сервис $ location, но в конце концов мне нужно было обернуть его в scope.apply. Я знаю, что это хорошо задокументировано, но это ускользнуло от меня. В одной строке angular.element (document) .scope (). $ Apply (angular.element (document) .injector (). Get ('$ location'). Path ('/ my / angular / url'))
acid_crucifix
25

Прежде всего, модифицированная версия вашего сервиса.

а)

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

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

Это возвращает объект, ничего нового здесь.

Теперь способ получить это из консоли

б)

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

в)

Одна из вещей, которую вы делали ранее, заключалась в том, что app.factory возвращает вам саму функцию или ее новую версию. Что не так. Чтобы получить конструктор, вам нужно будет либо сделать

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

Это возвращает конструктор ExampleService, который вы затем должны будете выполнить 'new'.

Или, в качестве альтернативы,

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

Это возвращает новый ExampleService () при внедрении.

ganaraj
источник
3
когда я это делаю, var $inj = angular.injector(['app']);консоль выдает Error: Unknown provider: $filterProvider from appв одном приложении и Error: Unknown provider: $controllerProvider from appв другом приложении ...
JustGoscha
@JustGoscha Как настроено ваше приложение? т.е. как работает строка (которая выглядит как) var app = angular.module ('app', []); выглядеть в вашем приложении.
Ганарадж
Я не совсем понимаю вопрос ... это выглядит так, как вы говорите, angular.module('app',[]);а затем есть службы, контроллеры и т. Д. В разных файлах, и все они определены, angular.module('app').factory('FeatureRegistry',function(){//code here});например,
JustGoscha
@JustGoscha Вот что я сделал, чтобы проверить. Я пошел в docs.angularjs.org/api в хром. Открыл консоль. Введите код в разделе a моего ответа, а затем введите код в разделе b .. Вы должны увидеть Hello World .. Можете ли вы попробовать это?
Ганарадж
14

Ответ @ JustGoscha точен, но когда мне нужен доступ, его можно набирать, поэтому я добавил его в конец файла app.js. Тогда все, что мне нужно набрать, - x = getSrv('$http')это получить сервис http.

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

Он добавляет его в глобальную область, но только в режиме отладки. Я поместил это внутрь @if DEBUGтак, чтобы я не оказался в рабочем коде. Я использую этот метод для удаления кода отладки из сборок prouduction.

boatcoder
источник
4

Платформа Angularjs Dependency Injection отвечает за внедрение зависимостей вашего модуля приложения в ваши контроллеры. Это возможно благодаря его инжектору.

Сначала вам нужно идентифицировать приложение ng и получить соответствующий инжектор. Приведенный ниже запрос работает для поиска вашего ng-приложения в DOM и получения инжектора.

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

В chrome, однако, вы можете указать на целевое приложение ng, как показано ниже. и использовать $0взломать и выпуститьangular.element($0).injector()

Как только у вас есть инжектор, получите любую услугу, внедренную в зависимости, как показано ниже

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

введите описание изображения здесь

Файз Мохамед Ханиф
источник