Sei que essa pergunta é antiga agora, mas depois de fazer uma tonelada de pesquisas sobre várias soluções para esse problema, acho que posso ter encontrado uma solução melhor.
ATUALIZAÇÃO 1: Desde a publicação desta resposta, adicionei todo esse código a um serviço simples que publiquei no GitHub. O repo está localizado aqui . Sinta-se à vontade para conferir mais informações.
ATUALIZAÇÃO 2: Essa resposta é ótima se tudo o que você precisa é de uma solução leve para obter folhas de estilo para suas rotas. Se você deseja uma solução mais completa para gerenciar folhas de estilo sob demanda em todo o aplicativo, confira o projeto AngularCSS do Door3 . Ele fornece muito mais funcionalidade refinada.
Caso alguém no futuro esteja interessado, aqui está o que eu criei:
1. Crie uma diretiva personalizada para o <head>
elemento:
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;
});
}
});
}
};
}
]);
Esta diretiva faz o seguinte:
- Ele compila (usando
$compile
) uma string html que cria um conjunto de <link />
tags para cada item no scope.routeStyles
objeto usando ng-repeat
e ng-href
.
- Anexa esse conjunto compilado de
<link />
elementos à <head>
tag.
- Em seguida, ele usa o
$rootScope
para ouvir '$routeChangeStart'
eventos. Para cada '$routeChangeStart'
evento, ele pega o $$route
objeto "atual" (a rota que o usuário está prestes a sair) e remove seus arquivos css parciais específicos da <head>
tag. Ele também pega o "próximo" $$route
objeto (a rota para a qual o usuário está prestes a ir) e adiciona qualquer um dos seus arquivos css parciais específicos à <head>
tag.
- E a
ng-repeat
parte da <link />
tag compilada lida com a adição e remoção de folhas de estilo específicas da página, com base no que é adicionado ou removido do scope.routeStyles
objeto.
Nota: isso requer que seu ng-app
atributo esteja no <html>
elemento, não em <body>
ou qualquer coisa dentro dele <html>
.
2. Especifique quais folhas de estilo pertencem a quais rotas usando o $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']
})
}]);
Essa configuração adiciona uma css
propriedade personalizada ao objeto usado para configurar a rota de cada página. Esse objeto é passado para cada '$routeChangeStart'
evento como .$$route
. Portanto, ao ouvir o '$routeChangeStart'
evento, podemos pegar a css
propriedade que especificamos e anexar / remover essas <link />
tags, conforme necessário. Observe que especificar uma css
propriedade na rota é completamente opcional, pois foi omitida no '/some/route/2'
exemplo. Se a rota não tiver uma css
propriedade, a <head>
diretiva simplesmente não fará nada para essa rota. Observe também que você pode até ter várias folhas de estilo específicas da página por rota, como no '/some/route/3'
exemplo acima, em que a css
propriedade é uma matriz de caminhos relativos às folhas de estilo necessárias para essa rota.
3. Você está pronto
Essas duas coisas configuram tudo o que é necessário e, na minha opinião, o código mais limpo possível.
Espero que ajude alguém que possa estar lutando com esse problema tanto quanto eu.
<link>
tags css nesse formato , com o Chrome mais recente, o servidor na minha máquina local (e "Desativar cache" ativado para simular as condições de "primeiro carregamento"). Eu imagino que pré-inserir uma<style>
tag no html parcial no servidor evitaria esse problema.