Angular: загрузить свойства среды перед настройкой / запуском
Я разрабатываю угловое приложение, и у этого приложения есть около 10 настраиваемых свойств (в зависимости от среды и клиента).
У меня были эти свойства в конфигурационных файлах json, но это действительно хлопотно: должны быть определенные сборки для env/company. Поэтому я хотел бы получить эти свойства один раз из бэкэнда при загрузке приложения.
Таким образом, чтобы сделать это, я создал провайдера
var app = angular.module('myApp', [...]);
app.provider('environment', function() {
var self = this;
self.environment;
self.loadEnvironment = function (configuration, $http, $q) {
var def = $q.defer();
$http(...)
.success(function (data) {
self.environment = Environment.build(...);
def.resolve(self.environment);
}).error(function (err) {
...
});
return def.promise;
};
self.$get = function(configuration, $http, $q) {
if (!_.isUndefined(self.environment)) {
return $q.resolve(self.environment);
}
return self.loadEnvironment(configuration, $http, $q);
};
}
app.config(... 'environmentProvider', function(... environment) {
...
//The problem here is that I can't do environment.then(...) or something similar...
//Environment does exists though, with the available functions...
}
Как правильно работать с этим провайдером, который выполняет вызов rest для заполнения его переменной среды?
Заранее спасибо!
1 ответ
Это отличный сценарий для изучения особенностей angularjs.
Предполагая, что вам действительно нужно загрузить данные среды перед загрузкой приложения, вы можете использовать угловые инструменты для загрузки среды, а затем объявить value
или constant
сохранить настройки среды до загрузки приложения.
Итак, вместо использования ng-app
чтобы запустить приложение, вы должны использовать angular.bootstrap
загрузить его вручную.
Наблюдения: вы не должны использовать
ng-app
после того, как вы загрузите приложение вручную, в противном случае ваше приложение будет загружаться с угловой системой по умолчанию без учета загрузки вашей среды. Также обязательно загрузите ваше приложение после объявления всех компонентов модуля; т.е. объявлять все контроллеры, сервисы, директивы и т. д., тогда вы вызываетеangular.bootstrap
Приведенный ниже код реализует решение, описанное ранее:
(function() {
var App = angular.module("myApp", []);
// it will return a promisse of the $http request
function loadEnvironment () {
// loading angular injector to retrieve the $http service
var ngInjector = angular.injector(["ng"]);
var $http = ngInjector.get("$http");
return $http.get("/environment-x.json").then(function(response) {
// it could be a value as well
App.constant("environment ", response.data);
}, function(err) {
console.error("Error loading the application environment.", err)
});
}
// manually bootstrap the angularjs app in the root document
function bootstrapApplication() {
angular.element(document).ready(function() {
angular.bootstrap(document, ["myApp"]);
});
}
// load the environment and declare it to the app
// so then bootstraps the app starting the application
loadEnvironment().then(bootstrapApplication);
}());