Javascript Angular JS-使服务可从控制器和视图全局访问
假设我们有以下服务:Javascript Angular JS-使服务可从控制器和视图全局访问,javascript,angularjs,Javascript,Angularjs,假设我们有以下服务: myApp.factory('FooService', function () { ... 然后,从一个控制器,我会说: myApp.controller('FooCtrl', ['$scope', 'FooService', function ($scope, FooService) { ... 问题分为两部分: 全局可访问性:如果我有100个控制器,并且所有控制器都需要访问该服务,我不想显式地将其注入100次如何使服务在全球范围内可用?目前我唯一能想到的是从根范围内
myApp.factory('FooService', function () { ...
然后,从一个控制器,我会说:
myApp.controller('FooCtrl', ['$scope', 'FooService', function ($scope, FooService) { ...
问题分为两部分:
找到了一个合理的解决方案。将其注入引导方法(run),并将其添加到根作用域。从那里,它将可用于所有控制器和视图
myApp.run(function ($rootScope, $location, $http, $timeout, FooService) {
$rootScope.foo = FooService;
....
重新阅读我上面提到的帖子,它没有确切地说“包装”。。。只是“抽象”,所以我猜海报是指同样的解决方案
为了彻底起见,(1)的答案是:
(2)的答案很简单:
{{doSomething()}}
添加Christopher的评论以确保其被看到:
@rob-根据最佳实践,工厂应注入 到需要使用它的控制器,而不是根作用域上。 如前所述,问题1实际上是反模式。如果你需要 工厂100次,你注射100次。几乎没什么额外的 缩小后的代码,并明确工厂的使用位置, 它使测试这些控制器变得更容易(也更明显) 对于模拟,通过将所需工厂全部列在 功能签名–Christopher WJ Rueber 2013年11月25日20:06
就直接在视图中访问服务而言,这似乎是非常没有角度的。将其绑定到控制器中的范围变量似乎比直接在UI中使用服务来帮助保持职责分离更好。补充问题1(全局访问性)我只想补充一点,为了避免缩小文件时出现问题(如果是这样的话),应该这样写:
this.app.run(["$rootScope", "Foo", function($rootScope, FooService) {
return $rootScope.fooService = FooService;
}
]);
考虑一个AuthService,它告诉您是否登录,通过NG显示保护一个功能(IE)。从这个角度来看,你可能想说一些类似于ng show='authService.isLoggedIn()'的话,但我不同意这是一种“正确”的方式。更简单的方法似乎是基于服务调用在控制器中设置范围变量,然后绑定到范围变量,而不是直接绑定到服务调用。职责分离!你所说的与上面的答案有什么不同?从功能上来说,如果这就是你所关心的,那就什么都没有了。这会让工作完成的。实际上,它将事物保持在正确的位置并提高可维护性。这是一个很好的实践,将有助于其他未来的开发人员在这方面的工作。在上面的示例中,我有一个指向控制器中的服务的指针。我听上去你就是这么说的?没有看到区别?听起来像是劈头?一个完美的答案。我想知道谷歌是否能提供更好的解决方案?当然,对于日志记录和分析等服务来说,这一点非常重要。是否有办法修改这一点,以便在服务定义中添加绑定?@sidonaldson这通常被认为是一种反模式。因为它提供了一个不太可测试的环境(因为假定服务在一个作用域上总是可用的)。这就是为什么在这个主题上看不到很多帖子的原因。@rob-根据最佳实践,工厂应该被注入到需要使用它的控制器中,而不是根作用域中。如前所述,问题1实际上是反模式。如果你需要工厂100次,你注射它100次。缩小后几乎不需要任何额外的代码,并且非常清楚工厂的使用位置,通过将所需的工厂都列在函数签名中,可以更轻松(更明显)地使用模拟来测试这些控制器。@chris-我同意,并且在使用Angular一段时间后得出了相同的结论。如果你在回答中清楚地表达了这一点,我会选择最佳答案(如果可能的话,以前没有覆盖过答案选择)。否则我可能会在有时间的时候编辑这篇文章。
this.app.run(["$rootScope", "Foo", function($rootScope, FooService) {
return $rootScope.fooService = FooService;
}
]);