6

在 Angular 被引导之前,是否可以访问工厂服务的方法,类似于下面的代码?

为了设置一些全局应用程序变量,我需要在 Angular 启动之前发出一些 AJAX 请求。我曾希望保留此逻辑和/或将响应存储在 Angular 服务中,并返回一个承诺......

<script src="scripts/app.js"></script>
<script src="scripts/factories/app.js"></script>

<script>
    angular.element(document).ready(function() {

        factoryName.startup().then(function() {
            angular.bootstrap(document, ['MyApp']);
        }, function(err) {
            console.log(error fetching bootstrap data);
        }

    });
</script>

是否有替代方法可用于获得类似行为?

4

2 回答 2

4

下面是一个在引导应用程序之前加载配置文件的示例。

对 bootstrap 的第一次调用是为了获得对 $http 和 $location 等角度服务的访问权限(此时您也可以注入自己的模块来访问自定义服务)。

加载配置文件后,为主应用程序调用 angular.bootstrap,并将加载的配置设置为注入的临时模块(rsacAppBootstrap)上的常量。

与使用运行块中的承诺集相比,这里至少有两个优点:

  1. 减少所有依赖于配置的承诺样板
  2. 能够使用 RequireJS 根据环境有条件地加载依赖项

自定义引导脚本:

angular.bootstrap().invoke(function ($http, $location) {

  var env = $location.search()._env || null;
  if (env === true) {
    env = null;
  }

  var configUri = 'config/env.json';
  if (env) {
    configUri = configUri.replace('json', env + '.json');
  }

  var rsacAppBootstrap = angular.module('rsacAppBootstrap', [])
    .run(function ($rootScope, $location, $window) {
      var env = $location.search()._env;
      $rootScope.$on('$locationChangeSuccess', function () {
        var newEnv = $location.search()._env;
        if (env !== newEnv) {
          $window.location.reload();
        }
      })
    });

  function bootstrap(config) {
    rsacAppBootstrap.constant('rsacConfig', config || {});
    angular.element(document).ready(function () {
      var modules = ['rsacApp', 'rsacAppBootstrap'];
      if (config.modules){
        config.modules.forEach(function(v){
          modules.push(v);
        })
      }
      angular.bootstrap(document, modules);
    });
  }

  $http.get(configUri)
    .success(function (config) {
      config._env = env;
      if (config.require) {
        require(config.require, function(){
          bootstrap(config);
        });
      } else {
        bootstrap(config);
      }
    })
    .error(function () {
      bootstrap();
    });

});

示例配置文件:

{
  "_meta": [
    "Development environment settings"
  ],

  "require":[
    "//code.angularjs.org/1.2.3/angular-mocks.js",
    "components/rsacMock/js/rsacMock.js"
  ],

  "modules":[
    "ngMockE2E",
    "rsacMock"
  ],

  "resources": { ... }

}
于 2013-12-03T22:54:38.950 回答
4

您可以在模块运行块中进行第一次服务调用。当稍后对这些变量进行服务调用时,您可以从 $http 的缓存中为它们提供服务,也可以显式缓存第一次调用的承诺。

// example
myApp.run(function(MyService) {
  // call your function when Angular starts up
  MyService.init();
});
于 2013-11-11T14:49:03.057 回答