Wiem, że to pytanie jest stare, ale po przeprowadzeniu wielu badań nad różnymi rozwiązaniami tego problemu, myślę, że mogłem znaleźć lepsze rozwiązanie.
AKTUALIZACJA 1: Od czasu opublikowania tej odpowiedzi dodałem cały ten kod do prostej usługi, którą opublikowałem na GitHub. Repozytorium znajduje się tutaj . Zapraszam do sprawdzenia, aby uzyskać więcej informacji.
AKTUALIZACJA 2: Ta odpowiedź jest świetna, jeśli potrzebujesz tylko lekkiego rozwiązania do pobierania arkuszy stylów dla twoich tras. Jeśli potrzebujesz bardziej kompletnego rozwiązania do zarządzania arkuszami stylów na żądanie w całej aplikacji, możesz sprawdzić projekt AngularCSS Door3 . Zapewnia znacznie bardziej szczegółową funkcjonalność.
Na wypadek, gdyby ktoś w przyszłości był zainteresowany, oto co wymyśliłem:
1. Utwórz niestandardową dyrektywę dla <head>
elementu:
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;
});
}
});
}
};
}
]);
Ta dyrektywa ma następujące znaczenie:
- Kompiluje (używając
$compile
) ciąg html, który tworzy zestaw <link />
tagów dla każdego elementu w scope.routeStyles
obiekcie przy użyciu ng-repeat
i ng-href
.
- Dołącza skompilowany zestaw
<link />
elementów do <head>
znacznika.
- Następnie używa
$rootScope
do nasłuchiwania '$routeChangeStart'
zdarzeń. Przy każdym '$routeChangeStart'
zdarzeniu pobiera „bieżący” $$route
obiekt (trasę, którą użytkownik ma zamiar opuścić) i usuwa ze <head>
znacznika jego częściowo specyficzne pliki css . Przechwytuje również „następny” $$route
obiekt (trasę, do której ma się udać użytkownik) i dodaje do <head>
znacznika dowolny ze swoich częściowo specyficznych plików css .
- A
ng-repeat
część zebranych <link />
uchwyty znaczników wszystkich dodawanie i usuwanie arkuszy stylów strona specyficznych oparciu o to, co dostaje dodawane lub usuwane z scope.routeStyles
obiektu.
Uwaga: wymaga to, aby twój ng-app
atrybut znajdował się na <html>
elemencie, a nie na <body>
lub cokolwiek wewnątrz <html>
.
2. Określ, które arkusze stylów należą do których tras, używając $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']
})
}]);
Ta konfiguracja dodaje css
właściwość niestandardową do obiektu, który jest używany do konfigurowania trasy każdej strony. Ten obiekt jest przekazywany do każdego '$routeChangeStart'
zdarzenia jako .$$route
. Tak więc podczas słuchania '$routeChangeStart'
zdarzenia możemy pobrać określoną przez nas css
właściwość i <link />
w razie potrzeby dołączyć / usunąć te tagi. Zauważ, że określenie css
właściwości na trasie jest całkowicie opcjonalne, ponieważ zostało pominięte w '/some/route/2'
przykładzie. Jeśli trasa nie ma css
właściwości, <head>
dyrektywa po prostu nie zrobi nic dla tej trasy. Zauważ również, że możesz mieć nawet wiele arkuszy stylów specyficznych dla strony na trasę, jak w '/some/route/3'
powyższym przykładzie, gdzie css
właściwość jest tablicą względnych ścieżek do arkuszy stylów potrzebnych dla tej trasy.
3. Gotowe
Te dwie rzeczy konfigurują wszystko, co było potrzebne, i moim zdaniem robi to z możliwie najczystszym kodem.
Mam nadzieję, że pomoże to komuś innemu, kto może borykać się z tym problemem tak samo jak ja.
<link>
tagów css w tym formacie , z najnowszym Chrome, serwerem na moim komputerze lokalnym (i włączonym „Wyłącz pamięć podręczną”, aby zasymulować warunki „pierwszego ładowania”). Wyobrażam sobie, że wstępne wstawienie<style>
tagu w części html na serwerze pozwoliłoby uniknąć tego problemu.