使用$ http.get调用响应初始化AngularJS常量

时间:2014-11-07 14:10:55

标签: javascript angularjs

如何通过响应GET请求来初始化我的angularjs应用程序。

例如: -

    angular.module('A',[]);
    angular.module('A').run( function ($rootScope,$http){
      $rootScope.safeApply = function (fn) {

                $http.get('url').success(function(result){

                    // This doesn't work. I am not able to inject 'theConstant' elsewhere in my application
                    angular.module('A').constant('theConstant', result);
                });                   
                var phase = $rootScope.$$phase;
                if (phase === '$apply' || phase === '$digest') {
                    if (fn && (typeof (fn) === 'function')) {
                        fn();
                    }
                } else {
                    this.$apply(fn);
                }
            };
      });

我希望在我的应用初始化时设置常量,并且能够在我的组件之间共享常量。

实现这一目标的最佳方法是什么?

3 个答案:

答案 0 :(得分:10)

this blog post中所述,您可以在引导应用之前初始化一个常量:

(function() {
    var app = angular.module("A", []);

    var initInjector = angular.injector(["ng"]);
    var $http = initInjector.get("$http");

    return $http.get("/path/to/data.json")
        .then(function(response) {
            app.constant("myData", response.data);
        })
        .then(function bootstrapApplication() {
            angular.element(document).ready(function() {
                angular.bootstrap(document, ["A"]);
            });
        });


}());

答案 1 :(得分:5)

初始化应用时$http.get的结果不可用。它仅在服务器提供时可用。因此,简单地将该值保持在模块中是不可能的。你冒着

的风险

然而,您可以执行的操作是将$http.get的调用包装在服务中,并将该服务注入您希望常量的任何位置。 (请注意,服务无法注入配置块。)

// grab the "constant"
angular.module('A').factory('almostConstant', function () {
  return $http.get('url').then(function(response) {
    return response.data;
  });
});

// use the "constant"
angular.module('A').controller('controller', function($scope, almostConstant) {
  almostConstant.then(function(data){
    $scope.almostConstant = data;
  });  
});

访问almostConstant值的稍微尴尬的模式是由于它的异步性质。它只是在一个未指定的时间可用,因此尝试以同步方式访问它可能会引入许多微妙的时间错误。


非常非角度的方法是直接在JS文件中编写常量。目前,您的服务器可以使用值回复'url'的请求。相反,您可以使用以下字符串来回复'url.js'的请求:

angular.module('A').constant('theConstant', result);

结果显然是你的常数。例如,如果你在后端使用php,它可能看起来像这样:

<?php
   header('Content-Type: application/javascript');
   $constant = retrieveMyConstant();
?>
angular.module('A').constant('theConstant', <?php echo $constant; ?>);

确保常量看起来像JavaScript值。如果它是一个字符串,请将其包装在'中,如果它是JSON对象,则写入其序列化等。

在此之后,您只需在url.js文件中添加一个指向index.html的脚本代码。

请注意,此解决方案是同步的,因此如果在服务器上检索常量需要一段时间,则会影响页面加载时间。

答案 2 :(得分:1)

我发现使用&#39;解决&#39;标准角度路由器或使用UI-Router时的属性是初始化应用程序的更好方法。

这是使用UI-Router时的方式: -

  1. 使用空内联模板定义顶级抽象状态,如下所示: -
  2. $stateProvider.state('root',{
      abstract:true,
      template:'<ui-view/>',
      resolve : {
          securityContext : function($http){
              return $http.get("/security/context");
          }
      }
    });
    });
    

    要解决的属性是整个应用程序所需要的。喜欢 - 安全令牌,当前登录用户等。

    1. 定义从上述状态继承的子状态。您的应用程序的每个部分都必须由一个州管理。
    2. $stateProvider.state('root.optosoft.home',{
        url:'/home',
        templateUrl : '/assets/home-module/partial/home/home.html',
        controller: 'HomeCtrl',
        resolve : {
             accounts : function(securityContext){
                  // Child state wil first wait for securityContext to get resolved first
            }
        }
      });