Я знаю, що це питання вже давнє, але, провівши багато досліджень різних рішень цієї проблеми, я думаю, що я міг прийти до кращого рішення.
ОНОВЛЕННЯ 1: Після публікації цієї відповіді я додав увесь цей код до простої послуги, яку я опублікував у GitHub. Репо знаходиться тут . Не соромтеся перевірити це для отримання додаткової інформації.
ОНОВЛЕННЯ 2: Ця відповідь чудова, якщо все, що вам потрібно, - це легке рішення для складання таблиць стилів для ваших маршрутів. Якщо ви хочете отримати більш повне рішення для керування таблицями стилів за запитом у всій програмі, ви можете перевірити проект AngularCSS Door3 . Він забезпечує набагато більш дрібну функціональність.
Якщо хтось у майбутньому зацікавиться, ось що я придумав:
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
об'єкт (маршрут, який користувач збирається покинути) та видаляє з <head>
тегу його часткові файли css . Він також захоплює "наступний" $$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 на сервері дозволить уникнути цієї проблеми.