В настоящее время у меня есть API, который возвращает URL-адрес файла CSS, который я хотел бы включить в мой весь сайт. Поступайте с этим изменением url, я не могу жестко закодировать URL. В настоящее время я работаю над "view1", но я хочу, чтобы он работал над всем сайтом. (поэтому попробуйте реализовать его в index.html). Я не уверен, что лучший способ сделать это, и я уверен, что мой подход неправильный. Любое понимание было бы полезно или решение моей проблемы.
Мое приложение отформатировано под патроны.
app/ --> all of the source files for the application
app.css --> default stylesheet
components/ --> all app specific modules
API/ --> Mock Slim API for testing
index.php --> Root for the API
view1/ --> the view1 view template and logic
view1.html --> the partial template
view1.js --> the controller logic
view1_test.js --> tests of the controller
view2/ --> the view2 view template and logic
view2.html --> the partial template
view2.js --> the controller logic
view2_test.js --> tests of the controller
app.js --> main application module
index.html --> app layout file (the main html template file of the app)
Вот View1, который в настоящее время работает
JS
'use strict';
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('/api/auth/test').
then(function(response) {
$scope.css = response.data.temp.css;
}, function(response) {
alert('Error retrieving css: ' + response);
});
}]);
HTML
<head>
<link ng-attr-href="{{css}}" rel="stylesheet" type="text/css">
</head>
Вот мои корневые файлы, которые не работают
JS
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
'ngRoute',
'myApp.authentication',
'myApp.view1',
'myApp.view2',
'myApp.version'
]).
config(['$routeProvider','$httpProvider','$locationProvider', function($routeProvider, $httpProvider, $locationProvider) {
$httpProvider.interceptors.push('TokenInterceptor');
// intercept API 401 responses and force authentication
$httpProvider.interceptors.push(function ($q, $location, AuthenticationService) {
//some code has been removed here
});
$routeProvider.otherwise({redirectTo: '/view1'});
}])
/*This is part of a test*/
.controller('', ['$scope', '$http', function($scope, $http) {
$http.get('/api/auth/test').
then(function(response) {
$scope.css = response.data.temp.css;
}, function(response) {
alert('Error retrieving css: ' + response);
});
}]);
/*This is part of a test*/
HTML
<head>
<link ng-attr-href="{{css}}" rel="stylesheet" type="text/css">
</head>
Вопрос 1: Есть ли лучший способ сделать это? <-this - это то, что я хочу
Вопрос 2: Если нет, почему это не работает? <- согласится на
Мои догадки в том, что HTML работает до JS, и когда JS запускается, чтобы изменить {{css}} на правильный ответ, слишком поздно, чтобы включить его. Но если это так, то почему это работает на View1, а не на корневом индексе?
Позвольте мне сначала ответить на ваш вопрос 2.
Когда угловые бутстрапы сначала пересекают узлы DOM, затем просматривают все соответствующие директивы, оценивают их, компилируют и, наконец, связывают их. Причина, по которой ваш второй фрагмент кода не работает, заключается в том, что ваш {{css}}
не имеет ничего общего, поскольку он не имеет надлежащей scope
привязки.
Что вы можете сделать, это на самом деле объявить ng-controller
на уровне <head>
, и пусть этот контроллер выполнит свою работу. Что-то вроде этого:
.controller('cssCtrl',['$scope','$http', function($scope,$http){
$http.get('/api/auth/test').
then(function(response) {
$scope.css = response.data.temp.css;
}, function(response) {
alert('Error retrieving css: ' + response);
});
}]
И в вашем html:
<head ng-controller="cssCtrl">
<link ng-attr-href="{{css}}" rel="stylesheet" type="text/css">
</head>
Вот пример plnkr, который демонстрирует, как это сделать.
ng-controller
пригодится здесь, так как вам действительно не нужно определять route
для него сам по себе. Обратите внимание, что ваш css не будет загружен, пока ваши угловые бутстрапы не cssCtrl
и ваш cssCtrl
будет cssCtrl
. Будет какая-то задержка в этом, и, следовательно, наш первый вопрос, есть ли у нас лучший способ сделать это?
Я бы сказал, если у вас есть условная логика представления, основанная на самом угловом приложении, то используйте ng-if
и ng-class
. Если вам нужны более низкие уровни, используйте ng-style
.
Если вы действительно загружаете всю новую таблицу стилей CSS на основе определенной конфигурации/настроек, я бы сказал, пусть сервер (бэкэнд) справится с этим. Сервер определит, какой тип css должен быть загружен на основе конфигурации (возможно, разные региональные приложения имеют разные стили css) и создаст свой сайт. Вашему внешнему приложению (угловому) просто нужно будет слушать сервер и загружать, не переваривая его.
Конечно, это не на 100% лучший способ. Если вам действительно нужен CSS-код, основанный на интерфейсе, то пойдите для него и создайте приложение таким образом! Только вы хорошо знаете этот пример использования приложения. Возможно, вы можете обернуть весь SPA в MainCtrl
и MainView
, и пусть каждая конфигурация разрешится сначала до манипуляции с DOM.
Какие серверные технологии вы используете? Я думаю, что было бы намного проще и менее проблематично извлекать файл CSS со стороны сервера и выводить его в статический файл CSS, который вы просто включаете на свою страницу index.html. Сначала будет выполняться код на стороне сервера, а ваш код на стороне клиента вообще не должен касаться этого.
Вы также можете проверить наличие файла и получить только новую копию, если текущая версия старше определенного времени.
Вам по-прежнему необходимо предоставить дополнительную информацию.
Если его маршрутизатор ui упрощает работу. Все, что вам нужно сделать, это получить CSS в контроллере родителя, из которого выведены другие URL-адреса. Обычно я стараюсь, чтобы все мои страницы наследовались от одного родителя, который обычно является пустой страницей.
Кроме того, поскольку ваш сайт зависит от этого файла css, я предлагаю отложить показ вашего сайта. Вы можете просто показать счетчик, пока CSS не получит от обещания, а затем примените его.
ng-controller
? В вашем случае вы должны рассмотреть возможность его привязки к<html>
или<head>
<head>
находится вне области действия контроллера. Директива была бы лучше