3

我想知道是否有一种方法可以使提供程序的配置不是在整个应用程序中唯一,而是在配置它的模块中唯一。

例如,我有一个模块“核心”,其中包含提供者的定义。然后我有模块“module1”和“module2”,它们使用提供程序,但必须以特定方式为特定模块配置它。

我发生的事情是在最后定义的模块中完成的配置覆盖了在应用程序中使用提供程序的所有其他模块中完成的配置。

我做了这个简单的 plunker 来举例说明:

var app = angular.module('app', ['module1','module2']);

angular.module('core',[])

.provider('movie', function () {
  var version;
  return {
    setVersion: function (value) {
      version = value;
    },
    $get: function () {
      return {
          title: 'The Matrix' + ' ' + version
      }
    }
  }
});

angular.module('module1',['core'])

.config(function (movieProvider) {
  movieProvider.setVersion('Reloaded');
})

.controller('ctrl1', function ($scope,movie) {
  $scope.title = movie.title;
  $scope.module = 'module1';
});


angular.module('module2',['core'])

.config(function (movieProvider) {
  movieProvider.setVersion('Revolutions');
})

.controller('ctrl2', function ($scope,movie) {
  $scope.title = movie.title;
  $scope.module = 'module2';
});

http://plnkr.co/edit/BI5nhmcdgzQZfZo56Koh?p=preview

4

1 回答 1

5

理论和其他无用的废话

在 Angular 提供程序中,$get 旨在返回所提供功能的单个实例;$get() 在提供者的每个实例化(如工厂)上重新执行。提供提供者定义的函数或对象仅被实例化一次(如服务)。

因此,要从提供程序中获取类似工厂的属性,您需要将特定于实例的属性保留在 $get; 范围内。并获得 $get 范围之外的类似服务的属性。

起初这似乎有点限制或迂回,但它允许您以非常漂亮的方式组合实例范围和全局范围的属性。

你的问题,特别是

具体到您的问题,如果我们只是var version进入$get,突然我们会得到您正在寻找的类似工厂的行为:

.provider('movie', function () {
  return {
    $get: function () {
      var version;

      var obj = {
          title: function() { return 'The Matrix' + ' ' + version; },
          setVersion: function (value) {
            version = value;
          }
      };

      return obj;
    }
  }
});

http://plnkr.co/edit/0m9qKzNuhCOOXTbrCQ1T?p=preview

更改范围(以及将标题更改为变量的函数,而不是在创建 obj 时静态生成的字符串),可以获得所需的输出:

This is module module1

Title: The Matrix Reloaded

This is module module2

Title: The Matrix Revolutions

这基本上就像一个工厂的ATM。

供应商真正脱颖而出的地方

为了进入一个更正常的提供者用例(我们想要结合全局和每个实例的范围),假设我们想要一个 API 提供者,它可以在不同的人的应用程序中使用几个不同的 API 之一 - 但是每个应用程序只有一个 API。我们希望我们的提供者看起来大致像这样 -

.provider('movie', function () {
  var imdbEndpoint;

  return {
    setApiEndpoint: function(newImdbEndpoint) {
      imdbEndpoint = newImdbEndpoint;
    },
    $get: function () {
      var version;

      var obj = {
          title: function() { return imdbEndpoint + ' says the The Matrix version is ' + ' ' + version; },
          setVersion: function (value) {
            version = value;
          }
      };

      return obj;
    }
  }
});

http://plnkr.co/edit/ZoSgQDpNdX8MOmet7xzM?p=preview

输出:这是模块 module1

Title: api.imdb.com says the The Matrix version is Reloaded

This is module module2

Title: api.imdb.com says the The Matrix version is Revolutions

所以现在我们的 API 端点 URL 是全局范围的(或基于每个应用程序),但是我们可以引用我们想要的任何电影,而不会混淆 Neo 位于矩阵的哪一层——因为这才是真正的意义,对吧?

于 2015-06-29T00:11:20.623 回答