在AngularJS中创建用户可覆盖的配置系统

时间:2014-10-22 14:46:15

标签: angularjs angular-promise angular-services angular-http

我正在使用基于angularJS的工具来构建图表,并且我想创建一个用户可覆盖的配置系统 - 即,默认值从一个配置文件加载,如果存在另一个配置文件则会被覆盖

这是我到目前为止所拥有的:

angular.module('axisJSApp')
  .provider('configProvider', function () {
    this.$get = function axisJSConfig($http, $q) {
      var defaultConfig = $http.get('default.config.yaml');
      var userConfig = $http.get('config.yaml');

      return $q.all([defaultConfig, userConfig]).then(function(values){
        var defaultConfigYaml = jsyaml.safeLoad(values[0].data);
        var userConfigYaml = jsyaml.safeLoad(values[1].data);
        return angular.extend(defaultConfigYaml, userConfigYaml);
      });
    };
  });

然后在我的控制器中:

angular.module('axisJSApp')
  .controller('MainCtrl', function (configProvider, $scope) {
    configProvider.then(function(appConfig){
      console.dir(appConfig); // Config loaded, everything else happens.
    });
  });

如果default.config.yaml和config.yaml都存在,这一切都正常。我的问题是,如果config.yaml不存在,如何让$ q.all()优雅地失败?

此外,有没有办法同步加载配置文件,所以我不必将我的整个控制器包装在.then()

谢谢!

1 个答案:

答案 0 :(得分:1)

我能想到的一种优雅地处理config.yaml不存在的方法是:

var userConfig = $http.get('config.yaml').then(
    function(response) {
        return response.data;
    },
    function(response) {
        if( response.status === 404 ) {
            response.data = {};
            return response;
        }
        else {
            return $q.reject(response);
        }
    }
);

return $q.all([defaultConfig, userConfig]).... // AS BEFORE

所以你通过在response.data中返回一个空对象(或任何符合你需要的东西)手动修复“不存在”的情况。

我想不出一种同步加载配置文件的优雅方式;如果您使用ngRoute,则可以使用路由的resolve配置(更多here)在控制器启动之前向控制器提供数据。