Angularjs 在不同模块中具有不同配置的提供商

Angularjs provider with different configurations in different modules

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

例如,我有一个模块 "core",其中包含提供程序的定义。然后我有模块 "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

理论和其他无用的废话

在 angular 提供者中,$get 旨在 return 所提供功能的单个实例; $get() 在提供者(如工厂)的每个实例化上都是 re-executed。提供提供者定义的函数或 object 仅实例化一次(如服务)。

因此,要从您的提供商处获取 factory-like 属性,您需要将 instance-specific 属性限制在 $get 范围内;并获取 $get.

范围之外的 service-like 属性

乍一看这似乎有点局限或迂回,但它允许您以非常巧妙的方式组合 instance-scoped 和 globally-scoped 属性。

你的问题,具体来说

具体针对您的问题,如果我们只是将 var version 移动到 $get,我们会突然得到您正在寻找的 factory-like 行为:

.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。

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

为了进入一个更正常的提供者用例(我们想要结合全局和 per-instance 范围),假设我们想要一个 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 是全局范围的(或在 per-application 的基础上)但是我们可以引用我们想要的任何电影而不会混淆矩阵的哪一层Neo 出现了 - 因为这就是它的真正意义,对吧?