【问题标题】:Initialize AngularJS Constant using $http.get call response使用 $http.get 调用响应初始化 AngularJS 常量
【发布时间】:2015-01-04 08:33:52
【问题描述】:

如何通过响应 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);
                }
            };
      });

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

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

【问题讨论】:

  • 什么是theValueFromHttpCall
  • @akonsu 更新了问题。在我的情况下,响应将是一个 JSON 对象。
  • 有趣。我猜想注入器已经在启动时定义了所有组件,所以我认为有必要直接使用它来启用您的场景。
  • @akonsu 你能详细说明一下吗?我应该参考一些参考资料/博客来完成这项工作....
  • 从服务器端获取json响应并在app_config中设置如下:Initialize angularJS app

标签: javascript angularjs


【解决方案1】:

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"]);
            });
        });


}());

【讨论】:

    【解决方案2】:

    在应用初始化时,$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;
      });  
    });
    

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


    这样做的一种非常非角度的方式是直接在 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 对象,则写入其序列化等。

    在此之后,您只需在您的index.html 文件中包含一个指向url.js 的脚本标签。

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

    【讨论】:

    • 就我而言,没有服务器端网页。所以我想我将不得不采用你建议的第一种方法。
    • 每次要读取常量值时都在调用服务器,这不是一个好的解决方案。
    • @Abhijeet 工厂方法被单次调用,所以在页面上单次调用$http.get,所以向服务器发送单次请求。随意在一个简单的例子中尝试一下。
    【解决方案3】:

    我发现在标准角度路由器或使用 UI-Router 时使用“解析”属性是初始化应用的更好方法。

    这是使用 UI-Router 时的做法:-

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

    要解析的属性是整个应用程序所需的。 Like - 安全令牌、当前登录用户等。

    1. 定义继承自上述状态的子状态。应用程序的每个部分都必须由状态管理。
    $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
          }
      }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 2017-05-06
      相关资源
      最近更新 更多