Javascript Angular JS - 使服务可从控制器和视图全局访问
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14571714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular JS - Make service globally accessible from controllers and view
提问by Robert Christian
Let's say we have the following service:
假设我们有以下服务:
myApp.factory('FooService', function () { ...
Then, from a controller, I would say:
然后,从控制器,我会说:
myApp.controller('FooCtrl', ['$scope', 'FooService', function ($scope, FooService) { ...
The two-part question is:
两部分的问题是:
- Global Accessibility: If I have 100 controllers and all need access to the service, I don't want to explicitly inject it 100 times. How can I make the service globally available?Only thing I can think of at the moment is wrapping it from within the root scope, which defeats the purpose.
- Accessibility from view: How can I access the service from within the view? This postsuggests wrapping the service from within the controller. If I am going to that length, seems I ought to just implement the functionality right on the root scope?
- 全局可访问性:如果我有 100 个控制器并且都需要访问该服务,我不想显式注入 100 次。 如何使服务在全球范围内可用?目前我唯一能想到的是从根范围内包装它,这违背了目的。
- 视图中的可访问性:如何从视图中访问服务? 这篇文章建议从控制器内部包装服务。如果我要达到那个长度,似乎我应该只在根范围内实现功能?
回答by Robert Christian
Found a reasonable solution. Inject it into the bootstrap method (run), and add it to the root scope. From there it will be available to all controllers and views.
找到了一个合理的解决方案。将其注入引导方法(run),并将其添加到根作用域。从那里它将可供所有控制器和视图使用。
myApp.run(function ($rootScope, $location, $http, $timeout, FooService) {
$rootScope.foo = FooService;
....
Re-reading the post I mentioned above, it didn't say "wrap" exactly... just "abstract", so I presume the poster was referring to this same solution.
重新阅读我上面提到的帖子,它并没有完全说“包装”......只是“抽象”,所以我认为海报指的是相同的解决方案。
For thoroughness, the answer to (1) is then:
为了彻底,对(1)的答案是:
myApp.controller('FooCtrl', ['$scope', function ($scope) {
// scope inherits from root scope
$scope.foo.doSomething();
...
and the answer to (2) is simply:
(2) 的答案很简单:
{{doSomething()}}
Adding Christopher's comment to make sure it's seen:
添加克里斯托弗的评论以确保它被看到:
@rob - According to best practices, the factory should be injected in to the controllers that need to use it, rather than on the root scope. As asked, question number one actually is the antipattern. If you need the factory 100 times, you inject it 100 times. It's barely any extra code when minified, and makes it very clear where the factory is used, and it makes it easier (and more obvious) to test those controllers with mocks, by having the required factories all listed in the function signature. – Christopher WJ Rueber Nov 25 '13 at 20:06
@rob - 根据最佳实践,工厂应该被注入到需要使用它的控制器中,而不是在根范围内。正如所问,第一个问题实际上是反模式。如果你需要工厂100次,你就注射100次。缩小后几乎没有任何额外的代码,并且非常清楚工厂的使用位置,并且通过在函数签名中列出所需的工厂,可以更容易(也更明显)使用模拟测试这些控制器。– Christopher WJ Rueber 2013 年 11 月 25 日 20:06
回答by James M
As far as accessing the service directly in the view, that seems exceedingly un-angular. Binding it to a scope variable in the controller seems like a better solution than using the service directly in the UI to help maintain separation of duties.
就直接在视图中访问服务而言,这似乎非常不合理。将它绑定到控制器中的范围变量似乎比直接在 UI 中使用服务来帮助维护职责分离更好的解决方案。
回答by tonatiuhnb
Complementing question #1 (Global accesibillity) I will only add that in order to avoid issues when minifiying the file (if that's the case) it should be written like this:
补充问题#1(全局可访问性)我只会补充一点,以避免在缩小文件时出现问题(如果是这种情况),它应该这样写:
this.app.run(["$rootScope", "Foo", function($rootScope, FooService) {
return $rootScope.fooService = FooService;
}
]);

