Я знаю, что этот вопрос устарел, но, проведя массу исследований различных решений этой проблемы, я думаю, что, возможно, придумал лучшее решение.
ОБНОВЛЕНИЕ 1. С момента публикации этого ответа я добавил весь этот код в простую службу, которую я разместил на GitHub. Репо находится здесь . Не стесняйтесь проверить это для получения дополнительной информации.
ОБНОВЛЕНИЕ 2: Этот ответ хорош, если все, что вам нужно, - это легкое решение для извлечения таблиц стилей для ваших маршрутов. Если вам нужно более полное решение для управления таблицами стилей по требованию во всем приложении, вы можете проверить проект Door3 AngularCSS . Он обеспечивает гораздо более детальную функциональность.
На случай, если кому-то в будущем интересно, вот что я придумал:
1. Создайте настраиваемую директиву для <head>
элемента:
app.directive('head', ['$rootScope','$compile',
function($rootScope, $compile){
return {
restrict: 'E',
link: function(scope, elem){
var html = '<link rel="stylesheet" ng-repeat="(routeCtrl, cssUrl) in routeStyles" ng-href="{{cssUrl}}" />';
elem.append($compile(html)(scope));
scope.routeStyles = {};
$rootScope.$on('$routeChangeStart', function (e, next, current) {
if(current && current.$$route && current.$$route.css){
if(!angular.isArray(current.$$route.css)){
current.$$route.css = [current.$$route.css];
}
angular.forEach(current.$$route.css, function(sheet){
delete scope.routeStyles[sheet];
});
}
if(next && next.$$route && next.$$route.css){
if(!angular.isArray(next.$$route.css)){
next.$$route.css = [next.$$route.css];
}
angular.forEach(next.$$route.css, function(sheet){
scope.routeStyles[sheet] = sheet;
});
}
});
}
};
}
]);
Эта директива выполняет следующие действия:
- Он компилирует (использует
$compile
) строку html, которая создает набор <link />
тегов для каждого элемента в scope.routeStyles
объекте, используя ng-repeat
и ng-href
.
- Он добавляет этот скомпилированный набор
<link />
элементов к <head>
тегу.
- Затем он использует
$rootScope
для прослушивания '$routeChangeStart'
событий. Для каждого '$routeChangeStart'
события он захватывает «текущий» $$route
объект (маршрут, который пользователь собирается покинуть) и удаляет свои частичные файлы css из <head>
тега. Он также захватывает «следующий» $$route
объект (маршрут, по которому собирается перейти пользователь) и добавляет к <head>
тегу любой из своих частичных файлов css .
- А
ng-repeat
часть скомпилированного <link />
тега обрабатывает все операции добавления и удаления таблиц стилей для конкретной страницы в зависимости от того, что добавляется или удаляется из scope.routeStyles
объекта.
Примечание: для этого требуется, чтобы ваш ng-app
атрибут находился на <html>
элементе, а не на <body>
чем-либо внутри <html>
.
2. Укажите, какие таблицы стилей каким маршрутам принадлежат, используя $routeProvider
:
app.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/some/route/1', {
templateUrl: 'partials/partial1.html',
controller: 'Partial1Ctrl',
css: 'css/partial1.css'
})
.when('/some/route/2', {
templateUrl: 'partials/partial2.html',
controller: 'Partial2Ctrl'
})
.when('/some/route/3', {
templateUrl: 'partials/partial3.html',
controller: 'Partial3Ctrl',
css: ['css/partial3_1.css','css/partial3_2.css']
})
}]);
Эта конфигурация добавляет настраиваемое css
свойство к объекту, которое используется для настройки маршрута каждой страницы. Этот объект передается каждому '$routeChangeStart'
событию как .$$route
. Таким образом, при прослушивании '$routeChangeStart'
события мы можем получить указанное css
свойство и добавлять / удалять эти <link />
теги по мере необходимости. Обратите внимание, что указание css
свойства в маршруте не является обязательным, так как оно было опущено в '/some/route/2'
примере. Если у маршрута нет css
свойства, <head>
директива просто ничего не сделает для этого маршрута. Также обратите внимание, что вы можете даже иметь несколько таблиц стилей для каждой страницы, как в '/some/route/3'
приведенном выше примере, где css
свойство представляет собой массив относительных путей к таблицам стилей, необходимых для этого маршрута.
3. Все готово.
Эти две вещи настраивают все, что было необходимо, и, на мой взгляд, делает это с максимально чистым кодом.
Надеюсь, что это поможет кому-то еще, кто, возможно, борется с этой проблемой так же сильно, как и я.
<link>
теги css в этом формате с последней версией Chrome, сервером на моем локальном компьютере (и «Отключить кеш» для имитации условий «первой загрузки»). Я полагаю, что предварительная вставка<style>
тега в партиал html на сервере позволит избежать этой проблемы.