Как установить базовый URL-адрес AngularjJS динамически на основе выбранной переменной среды?
У меня есть среда разработки и производства, в которой мой URL отличается:
продукция:
www.exmaple.com/page
развитие:
dev.environment/project/page
Я знаю, что я могу установить базовый URL в AngularJS с помощью
<base href='/project/' />
но это не помогает мне здесь. Прежде чем загружать приложение AngularJS, я получаю конфигурационный файл (в app.js, с оператором .run
, который читает переменную, которая имеет среду:
]).run([
'$rootScope',
'$http',
function (
$rootScope,
$http
) {
var configDeferred = $q.defer();
// fetch config and set the API
$http.get('config.json').then(function(response) {
$rootScope.config = response.data;
configDeferred.resolve();
});
// Wait for the config to be loaded, then go to state
$rootScope.$on('$stateChangeStart', function (event, next, current) {
event.preventDefault();
$q.all([configDeferred.promise]).then(function() {
$state.transitionTo(next.name);
return;
});
});
Есть ли способ динамически установить базовый URL-адрес на основе выбранного файла конфигурации в AngularJS (возможно, с .htaccess)?
Попытка 1:
Попробуйте получить конфигурацию через .run
и установите базовый url через ng-href:
Отредактируйте следующую строку кода в приложении app.js:
// fetch config and set the API
$http.get('config.json').then(function(response) {
$rootScope.config = response.data;
$rootScope.baseUrl = response.data.baseUrl; // '/project/'
configDeferred.resolve();
});
и в моем index.html:
<base ng-href="{{baseUrl}}" />
Похоже, что это не работает: когда я изменяю атрибут href тега на ng-href, он правильно загружает контент, но меняет URL-адрес на dev.environment/page
вместо dev.environment/project/page
UPDATE:
Файл конфигурации:
{
"mode": "development",
"baseUrl": "/project/"
}
Ответы
Ответ 1
Я лично делаю такие вещи с помощью grunt
.
Когда я запускаю свой angular -app, у меня есть несколько задач:
> grunt run --target=dev
> grunt run --target=prod
> grunt build --target=dev
> grunt build --target=prod
> etc...
Затем зажмите с помощью модуля grunt-preprocess
замену строк:
Мой файл constants.tpl.js
анализируется:
[...]
baseUrl: '/* @echo ENV_WS_URL */',
[...]
и URL-адрес заполнен.
Есть бесконечные возможности (замена строк, копирование файлов и т.д.).
Выполняя это с помощью grunt, убедитесь, что файлы конфигурации dev не входят в систему производства, например.
Я могу добавить больше деталей, если вы заинтересованы, но я хотел показать вам другой подход.
отредактируйте пример gruntFile:
'use strict';
module.exports = function(grunt) {
/**
* Retrieving current target
*/
var target = grunt.option('target') || 'dev';
var availableTargets = [
'dev',
'prod'
];
/**
* Load environment-specific variables
*/
var envConfig = grunt.file.readJSON('conf.' + target + '.json');
/**
* This is the configuration object Grunt uses to give each plugin its
* instructions.
*/
grunt.initConfig({
env: envConfig,
/*****************************************/
/* Build files to a specific env or mode */
/*****************************************/
preprocess: {
options: {
context: {
ENV_WS_URL: '<%= env.wsUrl %>'
}
},
constants: {
src: 'constants.tpl.js',
dest: 'constants.js'
}
},
karma: {
unit: {
configFile: '<%= src.karma %>',
autoWatch: false,
singleRun: true
},
watch: {
configFile: '<%= src.karma %>',
autoWatch: true,
singleRun: false
}
}
});
/****************/
/* Plugins load */
/****************/
grunt.loadNpmTasks('grunt-preprocess');
/*******************/
/* Available tasks */
/*******************/
grunt.registerTask('run', 'Run task, launch web server for dev part', ['preprocess:constants']);
};
Теперь команда:
> grunt run --target=dev
создаст новый файл с URL-адресом
Ответ 2
asumming вы создали службу, которая получает объект конфигурации с сервера
app.run(function($rootScope, yourService){
yourService.fetchConfig(function(config){
$rootScope.baseUrl = config.baseUrl;
})
});
Разметка
<html ng-app="yourApp">
<head>
<base ng-href="{{baseUrl}}">
......
Примечание
- Если ваша служба использует $http или $resource, вы должны быть в порядке
- Если вместо этого вы используете jQuery ajax-вызовы, вы должны запустить $rootScope. $apply() после установки переменных в область.
Ответ 3
Использование базовых URL-адресов может быть не лучшим, потому что это может также испортить работу якорных тегов и может привести к нежелательной навигации. Подход, который вы должны прочитать конфигурацию из XML файла, идеален, и это то, что я сделал:
1. Прежде чем инициализировать приложение angular, прочитайте переменную из вашего файла конфигурации:
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET", "config.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
пусть ваш config.xml имеет такое поле
<?xml version="1.0" encoding="utf-8" ?>
<config>
<url>http://dev/ur/</url>
</config>
Теперь вы вводите константу в свое приложение для этого, я руководствовался Eddiec и Cd
var myApp= angular.module("App", ["ui.router"]).constant('BASE_URL',
xmlDoc.getElementsByTagName("url")[0].childNodes[0].nodeValue);
3. Вы можете использовать BASE_URL в любом месте вашего приложения, которое вам нужно вводить, так как я использовал его, чтобы избежать жестко закодированных путей в ui.router.js
var routeResolver = function ($stateProvider, $urlRouterProvider,BASE_URL){
$stateProvider
.state('home', {
url: "/Home",
views: {
"main-view": {
templateUrl: BASE_URL+"/views/Home.htm",
controller: "homeCtrl",
resolve: {
}
}
}
})
}
myApp.config(routeResolver);
надеюсь, что это поможет приветствовать!
Ответ 4
Я попытался решить эту проблему, и я действительно не хочу помещать свой базовый путь в некоторый файл конфигурации. Мы работаем со многими разработчиками в нашем приложении, и каждый из них имеет разные рабочие условия. Наконец я обнаружил решение, которым я не очень горжусь, но он работает как шарм. Это требует только одного: PHP.
Итак, вместо того, чтобы писать базовый href с вашим JS в голове, попробуйте следующее:
<?php
$path = dirname($_SERVER['SCRIPT_NAME']);
$uri = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].$path.'/';
echo '<base href="' . $uri . '" />';
?>
Если у вас уже есть PHP на вашем сервере, то это только вопрос переименования вашего index.html
в index.php
(также не забывайте о .htaccess
, если он у вас есть).
Я знаю, что это решение не подходит для всех, это не предполагается, это просто мое решение проблемы для тех, у кого PHP уже есть на сервере. Надеюсь, это поможет хотя бы некоторым из вас:)