Инициализировать константу AngularJS с помощью ответа на вызов http.get $ http.get

Как я могу инициализировать мою консольную программу appantant с ответом на запрос GET.

Например :-

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

Я хочу установить константу, пока мое приложение будет инициализировано и сможет делиться константой через мои компоненты.

Каков наилучший подход для этого?

Ответы

Ответ 1

Результат $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;
  });  
});

Немного неудобный режим доступа к значению вашего почти константы обусловлен его асинхронным характером. Он просто доступен в неуказанное время, поэтому попытка получить доступ к нему синхронно может привести к множеству тонких ошибок времени.


Очень не угловатым способом сделать это было бы написать вашу константу в 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

Как поясняется в этом сообщении в блоге, вы можете инициализировать константу перед загрузкой приложения:

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


}());

Ответ 3

Я понял, что использование свойств "разрешить" либо в стандартном угловом маршрутизаторе, либо при использовании UI-Router - лучший способ инициализировать ваше приложение.

Так было и при использовании UI-Router: -

  1. Определите абстрактное состояние верхнего уровня с пустым встроенным шаблоном:
$stateProvider.state('root',{
  abstract:true,
  template:'<ui-view/>',
  resolve : {
      securityContext : function($http){
          return $http.get("/security/context");
      }
  }
});
});

Свойство, которое нужно решить, - это то, что требуется в вашем приложении. Как - токен безопасности, в настоящее время зарегистрированный пользователь и т.д.

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