30

假设我们有以下服务:

myApp.factory('FooService', function () { ...

然后,从控制器,我会说:

myApp.controller('FooCtrl', ['$scope', 'FooService', function ($scope, FooService) { ...

两部分的问题是:

  1. 全局可访问性:如果我有 100 个控制器并且都需要访问服务,我不想显式地注入 100 次。 我怎样才能使服务在全球范围内可用? 目前我唯一能想到的就是将它从根范围内包装起来,这违背了目的。
  2. 视图中的可访问性:如何 从视图中访问服务?这篇文章建议从控制器中包装服务。如果我要达到那个长度,似乎我应该只在根范围内实现该功能?
4

3 回答 3

39

找到了合理的解决方案。将其注入到引导方法(运行)中,并将其添加到根范围。从那里它将可用于所有控制器和视图。

myApp.run(function ($rootScope, $location, $http, $timeout, FooService) {
    $rootScope.foo = FooService;
    ....

重新阅读我上面提到的帖子,它并没有准确地说“包装”......只是“抽象”,所以我认为海报指的是同样的解决方案。

为彻底起见,(1)的答案是:

myApp.controller('FooCtrl', ['$scope', function ($scope) { 
    // scope inherits from root scope
    $scope.foo.doSomething();
    ...

(2)的答案很简单:

{{doSomething()}}

添加克里斯托弗的评论以确保它被看到:

@rob - 根据最佳实践,工厂应该被注入到需要使用它的控制器中,而不是在根范围内。如前所述,第一个问题实际上是反模式。如果你需要工厂 100 次,你注入它 100 次。缩小后几乎没有任何额外的代码,并且非常清楚工厂的使用位置,并且通过在函数签名中列出所需的工厂,使用模拟测试这些控制器变得更容易(也更明显)。——Christopher WJ Rueber 2013 年 11 月 25 日 20:06

于 2013-01-28T21:50:02.837 回答
6

就直接在视图中访问服务而言,这似乎非常不合时宜。将它绑定到控制器中的范围变量似乎比直接在 UI 中使用服务来帮助保持职责分离更好的解决方案。

于 2013-01-28T23:12:12.687 回答
6

补充问题 #1(全局可访问性)我只会补充一点,以避免在缩小文件时出现问题(如果是这样的话),它应该这样写:

this.app.run(["$rootScope", "Foo", function($rootScope, FooService) {
    return $rootScope.fooService = FooService;
  }
]);
于 2013-05-23T16:39:06.773 回答