Инициализировать константу 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: -
- Определите абстрактное состояние верхнего уровня с пустым встроенным шаблоном:
$stateProvider.state('root',{
abstract:true,
template:'<ui-view/>',
resolve : {
securityContext : function($http){
return $http.get("/security/context");
}
}
});
});
Свойство, которое нужно решить, - это то, что требуется в вашем приложении. Как - токен безопасности, в настоящее время зарегистрированный пользователь и т.д.
- Определите дочернее состояние, наследующее состояние выше. Каждая часть вашего приложения должна управляться государством.
$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
}
}
});