Angular:在配置/运行之前加载环境属性

时间:2016-10-18 11:51:36

标签: angularjs environment-variables angular-promise angular-http angular-providers

我正在开发一个角度应用程序,这个应用程序有大约10个可配置属性(取决于环境和客户端)。

我在json配置文件中有这些属性,但这真的很麻烦:每个env / company必须有特定的构建。所以我想从应用程序加载的后端检索一次这些属性。

所以为了做到这一点,我创建了一个Provider

var app = angular.module('myApp', [...]);
app.provider('environment', function() {
    var self = this;
    self.environment;

    self.loadEnvironment = function (configuration, $http, $q) {
        var def = $q.defer();
        $http(...)
        .success(function (data) {
            self.environment = Environment.build(...);
            def.resolve(self.environment);
        }).error(function (err) {
            ...
        });
        return def.promise;
    };

    self.$get = function(configuration, $http, $q) {
        if (!_.isUndefined(self.environment)) {
            return $q.resolve(self.environment);
        }
        return self.loadEnvironment(configuration, $http, $q);
    };
}
app.config(... 'environmentProvider', function(... environment) {
    ...
    //The problem here is that I can't do environment.then(...) or something similar... 
    //Environment does exists though, with the available functions... 
}

如何正确使用执行休息调用的Provider来填充他的环境变量?

提前致谢!

1 个答案:

答案 0 :(得分:1)

这是探索angularjs功能的绝佳方案。

假设您确实需要在加载应用之前加载环境数据,您可以使用角度工具加载环境,然后在app之前声明valueconstant来存储您的环境配置引导程序。

因此,您必须使用angular.bootstrap手动引导它,而不是使用ng-app来启动您的应用。

  

观察:手动引导应用后,您不能使用ng-app,否则您的应用会使用角度默认系统加载而不考虑您的环境加载。此外,确保在声明所有模块组件后引导应用程序;即声明所有控制器,服务,指令等,然后,你打电话给angular.bootstrap

以下代码实现了前面描述的解决方案:

(function() {
    var App = angular.module("myApp", []);

    // it will return a promisse of the $http request
    function loadEnvironment () {
        // loading angular injector to retrieve the $http service
        var ngInjector = angular.injector(["ng"]);
        var $http = ngInjector.get("$http");

        return $http.get("/environment-x.json").then(function(response) {
            // it could be a value as well
            App.constant("environment ", response.data);
        }, function(err) {
            console.error("Error loading the application environment.", err)
        });
    }

    // manually bootstrap the angularjs app in the root document
    function bootstrapApplication() {
        angular.element(document).ready(function() {
            angular.bootstrap(document, ["myApp"]);
        });
    }

    // load the environment and declare it to the app
    // so then bootstraps the app starting the application
    loadEnvironment().then(bootstrapApplication);
}());