How can I test an AngularJS service from the console?
我有这样的服务:
1 2 3 4 5 6
| angular.module('app').factory('ExampleService', function(){
this.f1 = function(world){
return 'Hello '+world;
}
return this;
}) |
我想从javascript控制台测试它并调用该服务的函数f1()。
我该怎么做?
tldr:在一行中,您要查找的命令是:
1
| angular.element(document.body).injector().get('serviceName') |
深俯冲
AngularJS使用依赖注入(DI)将服务/工厂注入到组件、指令和其他服务中。因此,要获得服务,您需要首先获得AngularJS的注入器(注入器负责连接所有依赖项并将它们提供给组件)。
要获得应用程序的注入器,您需要从角处理的元素中获取它。例如,如果您的应用程序注册在body元素上,则称为injector = angular.element(document.body).injector()。
从检索到的injector中,您可以得到任何您喜欢的injector.get('ServiceName')服务。
关于这个答案的更多信息:无法从角度检索喷油器更重要的是:从遗留代码调用angularjs
获取特定元素的$scope的另一个有用技巧。使用开发人员工具的DOM检查工具选择元素,然后运行以下行($0始终是所选元素):angular.element($0).scope()
- 有趣。那么,为什么可以在角度文档上完成呢?顺便说一下,它也在HTML上定义了NG应用程序。
- 我不知道……
- 我也必须这样做才能使它发挥作用。顺便说一下,angular.element('*[ng-app]').injector()适用于所有情况。
- 如果出现错误"selectors not implemented"executing angular.element("html"),则可以使用chrome$0功能。选择HTML元素,转到控制台并运行angular.element($0).injector()。
- document也起作用:angular.element(document).injector().get('serviceName')。
- FYI I had to use document.body on chrome
- 仅供参考,我想使用$location服务,但最终我需要将其包装在scope.apply中。我知道这是有据可查的,但我忘记了。在一行angular.element(doc ument.scope()$apply(angular.element(doc‌&8203;ument).injector().ge‌&8203;t("$location").path(‌&8203;'/my/angular/url'))
- angular.element(document.queryselector("*[ng app]")).injecto‌&8203;r().get("myservice")在没有jquery的情况下为我工作。
- 救了我的时间!!!!
- 我想知道如何使用过滤器。我没有通过互联网搜索找到太多,然后我意识到$filter只是一个可以类似地调用的服务。尝试通过设置stackoverflow.com/a/37399332/3232832来帮助角度初学者。希望有帮助。很好的问题和答案,这是一个非常方便的角度工具!
- 好的,谢谢你的江户秘技!
- 令人惊叹的!刚刚用recompile函数创建了一个chrome代码段。这样我就可以执行recompile($0),并且只对需要的元素进行角度重新编译,避免重新加载整个页面。
- 当尚未构造DOM时,它将不起作用。
- 确保您也启用了调试信息:angular.reloadWithDebugInfo();。
首先,您的服务的修改版本。
a)
1 2 3 4 5 6 7 8 9
| var app = angular.module('app',[]);
app.factory('ExampleService',function(){
return {
f1 : function(world){
return 'Hello' + world;
}
};
}); |
这将返回一个对象,这里没有新对象。
现在从控制台获得这个的方法是
b)
1 2 3
| var $inj = angular.injector(['app']);
var serv = $inj.get('ExampleService');
serv.f1("World"); |
c)
你之前在那里做的一件事是假设app.factory返回函数本身或它的新版本。事实并非如此。为了得到一个构造函数,你要么要做
1 2 3 4 5 6 7
| app.factory('ExampleService',function(){
return function(){
this.f1 = function(world){
return 'Hello' + world;
}
};
}); |
这将返回一个exampleService构造函数,您接下来必须对其执行"new"。
或者,
1 2 3 4 5
| app.service('ExampleService',function(){
this.f1 = function(world){
return 'Hello' + world;
};
}); |
这将在注入时返回新的exampleService()。
- 当我执行var $inj = angular.injector(['app']);时,控制台在一个应用程序中抛出Error: Unknown provider: $filterProvider from app,在另一个应用程序中抛出Error: Unknown provider: $controllerProvider from app…
- @Justgoscha你的应用程序是如何配置的?也就是说,一行(看起来像)var app=angular.module('app',[]);在你的app中看起来像什么。
- 我不完全理解这个问题。就像你说的angular.module('app',[]);,然后在不同的文件中有服务、控制器等,它们都被定义为angular.module('app').factory('FeatureRegistry',function(){//code here});。
- @Justgoscha是我做的测试。我去了chrome的docs.angularjs.org/api。打开控制台。在答案的A部分键入代码,然后在B部分键入代码。你应该看看"你好世界"。你能试试吗?
- 是的,这很管用。谢谢!…现在我需要找出我的代码有什么问题…
@Justgoscha的答案是"点对点",但当我想要访问时,这是一个需要输入的东西,所以我把它添加到了app.js的底部。然后我只需要输入x = getSrv('$http')就可以获得HTTP服务。
1 2 3 4 5 6
| // @if DEBUG
function getSrv(name, element) {
element = element || '*[ng-app]';
return angular.element(element).injector().get(name);
}
// @endif |
它将它添加到全局作用域,但只在调试模式下添加。我把它放在@if DEBUG中,这样我就不会在生产代码中使用它了。我使用这个方法从工程构建中删除调试代码。
AngularJS依赖注入框架负责将应用程序模块的依赖注入控制器。这可以通过其喷油器实现。
您需要首先识别NG应用程序并获取相关的注入器。下面的查询用于在DOM中查找NG应用程序并检索注入器。
1
| angular.element('*[ng-app]').injector() |
然而,在Chrome中,您可以指向目标NG应用程序,如下所示。使用$0黑客并发布angular.element($0).injector()。
一旦您拥有了注入器,就可以获得如下所示的任何依赖项注入服务
1 2
| injector = angular.element($0).injector();
injector.get('$mdToast'); |