在AngularJS中注入配置

bin*_*ant 6 angularjs

我有一个配置,我希望能够注入Angular服务,指令等.这样做的最佳方法是什么?

我正在玩制作配置模块的想法:

'use strict';
angular.module('config', [])
Run Code Online (Sandbox Code Playgroud)

但是我不确定如何构造将被注入的实际配置对象的对象文字:

angular.module('myModule', ['ngResource', 'config'])
  .factory('myservice', function ($resource) {
        return $resource(config.myservice,{}, {
          // whatever
        })
  });
Run Code Online (Sandbox Code Playgroud)

将config作为服务公开并注入它是否可以?

Flo*_*ian 9

我会说,策略会有所不同,具体取决于您拥有的配置类型,但您有以下几种选择:

模块宽常数

如果你只需要几个常量,你可以使用.value(),如下所示:

var app;

app = angular.module("my.angular.module", []);

app.value("baseUrl", "http://myrestservice.com/api/v1");

//injecting the value
app.controller("MyCtrl", ['baseUrl', function (baseUrl) {
  console.log(baseUrl); // => "http://myrestservice.com/api/v1"
}]);
Run Code Online (Sandbox Code Playgroud)

请在此处查看更详细的答案.

获取config/config服务

我个人喜欢做的是正常通过服务从其他地方获取我的配置.没关系,如果这是一个远程位置或只是静态信息.

var app;

app = angular.module("my.angular.config", []);

app.service('Configuration', [function() {
  return {
    getbaseUrl: function() { return "http://myrestservice.com/api/v1" },
    getConfig: function() {
      return {
        answer: 42,
        question: "??"
      }
    }
  }
}]):
Run Code Online (Sandbox Code Playgroud)

编辑:外部提取示例:

var app;

app = angular.module('my.module.config', []);

app.factory('ConfigurationData', ['$http', '$q', function(http, q) {
  var deferredConfig = q.defer();

  //error handling ommited
  http.get('http://remote.local/config.json').success(function(data) {
    return deferredConfig.resolve(data);
  });

  return {
    getConfig: function() {
      return deferredConfig.promise;
    }
  };
}]);
Run Code Online (Sandbox Code Playgroud)

使用此服务,您可以将配置注入其他服务,但是,您可能会遇到计时问题,因为您必须在配置之前注入并解决服务提供的承诺:

var app;

app = angular.module("my.other.module", ['my.module.config']);

app.factory('MyAwesomeService', ['ConfigurationData', function(config) {
  config.getConfig().then(function(config) {
    //do something with your config.
  });
}]);
Run Code Online (Sandbox Code Playgroud)

你可以在这里获得更好的控制,因为你可以对不同的输入做出反应.同样,这取决于您的用例.如果您需要用于构造配置的其他逻辑,则可以在此处使用工厂.

最后,如果您想要更多地控制配置,您可以制作一个

定制提供商

提供商可能非常有用,但我认为它们设计起来有点困难.考虑到baseUrl应用程序运行所需的配置,您可以为需要baseUrl此类值的服务编写提供程序:

var app;

app = angular.module('my.angular.module', []);

app.provider("RestServiceProvider", function(){

  this.baseUrl = 'http://restservice.com';

  this.$get = function() {
    var baseUrl = this.baseUrl;
    return {
        getBaseUrl: function() { return this.baseUrl; }
    }
  };

  this.setBaseUrl = function(url) {
    this.baseUrl = url;
  };
});
Run Code Online (Sandbox Code Playgroud)

这可以让你在应用程序的配置阶段做很酷的事情:

app.config(['RestserviceProvider', function(restServiceProvider) {

  restServiceProvider.setBaseUrl('http://wwww.myotherrestservice.com');

}]);
Run Code Online (Sandbox Code Playgroud)

您在服务/控制器/等中获取的每个实例.的RestService,现在将有baseUrl来自你注入那一刻的配置相集.

有关更详细的概述,我建议这个要点.


And*_* Ho 7

创建仅具有服务或指令(或两者)的独立模块是制作与应用程序无关的角度代码的好方法.如果你这样做,你可以轻松地获取.js文件并将其放入任何项目中,你需要做的就是将它注入到你的应用程序中,它才能正常工作.

所以做以下事情:

angular.module('config', [])
    .factory('config', function() {
        return {
            theme : 'nighttime',
            cursor : 'sword',
            ...
        };
    });
Run Code Online (Sandbox Code Playgroud)

然后你可以将它注入任何应用程序,如下所示:

angular.module('myModule', ['config'])
    .factory('myservice', function (config) {
        var theme = config.theme;
        var cursor = config.cursor;
        // do stuff with night-time swords!
    });
Run Code Online (Sandbox Code Playgroud)

这实际上是angular-ui团队打包所有指令的方式,每个指令都包含在自己的模块中,这使得其他人可以轻松地获取该代码并在其所有应用程序中重用它.