如何从控制台测试AngularJS服务?


395

我有类似的服务:

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

我想从JavaScript控制台对其进行测试,然后调用f1()该服务的功能。

我怎样才能做到这一点?

Answers:


713

TLDR:一行您正在寻找的命令:

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

深潜

AngularJS使用依赖注入(DI)将服务/工厂注入到您的组件,指令和其他服务中。所以,你需要做的就是一个服务是什么,以获得注入第一AngularJS的(喷油器是负责接线了所有的依赖关系和它们提供给组件)。

要获取应用程序的注入器,您需要从angular正在处理的元素中获取它。例如,如果您的应用程序已在您调用的body元素上注册injector = angular.element(document.body).injector()

从检索到的内容中,injector您可以享受所需的任何服务injector.get('ServiceName')

关于此问题的更多信息,请参见:无法从angular检索注入器在
这里甚至更多:从旧版代码调用AngularJS


获取$scope特定元素的另一个有用技巧。使用开发人员工具的DOM检查工具选择元素,然后运行以下行($0始终为选定元素):
angular.element($0).scope()


70
我还必须这样做才能使其正常工作。顺便说一句,angular.element('*[ng-app]').injector()应该适用于所有情况。
Francesc Rosas

4
如果在执行angular.element('html')时遇到错误“未实现选择器”,则可以使用Chrome $ 0功能。选择html元素,进入控制台并运行angular.element($ 0).injector()
Marek

9
document也可以使用:angular.element(document).injector().get('serviceName')
Tamlyn

1
仅供参考,我必须在Chrome上使用document.body
凯文(Kevin)

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;
        }
    };
});

这将返回一个对象,此处无新内容。

现在从控制台获取此内容的方法是

b)

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

C )

您之前在此处所做的一件事是假设app.factory返回了函数本身或函数的新版本。事实并非如此。为了获得构造函数,您要么必须要做

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

这将返回ExampleService构造函数,您接下来将必须对其执行“新操作”。

或者,

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

这将在注入时返回新的ExampleService()。


3
当我这样做时var $inj = angular.injector(['app']);,控制台会Error: Unknown provider: $filterProvider from app在一个应用程序和Error: Unknown provider: $controllerProvider from app另一个应用程序中抛出一个……
JustGoscha 2013年

@JustGoscha您的应用程序如何配置?即一行(看起来像)如何var app = angular.module('app',[]); 看起来像在您的应用中。
ganaraj

我没有完全理解这个问题。看起来就像你说的那样 angular.module('app',[]);,然后在不同文件中有服务,控制器等,它们的定义都一样angular.module('app').factory('FeatureRegistry',function(){//code here});,例如
JustGoscha 2013年

@JustGoscha这是我所做的测试。我去了chrome中的docs.angularjs.org/api。打开控制台。在我的答案的a部分中键入代码,然后在b部分中键入代码。您应该看到Hello World。
ganaraj

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以免最终在生产代码中出现。 我使用这种方法从生产版本中删除调试代码。


4

Angularjs依赖注入框架负责将应用程序模块的依赖关系注入到控制器中。通过其注射器可以做到这一点。

您需要首先识别ng-app并获取关联的注射器。以下查询可在DOM中找到您的ng-app并检索注射器。

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

但是,在chrome中,您可以如下所示指向目标ng-app。并使用$0hack和问题angular.element($0).injector()

拥有注入器后,请获取以下依赖项注入服务

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

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.