J'essaye d'ajouter dynamiquement des CSS à ma tête HTML à l'aide de js angulaires. Voici un exemple de code
<div ng-repeat="stylesheet in stylesheets">
<link href="/myapp/{{stylesheet.href}}" type="{{stylesheet.type}}" rel="stylesheet" media="{{stylesheet.media}}" title="{{stylesheet.title}}" />
</div>
Ce code fonctionne comme prévu, mais lorsque le navigateur charge la page, il tente de récupérer les ressources css avec des modèles angularjs bruts et je vois "erreur 404 non trouvée" dans l'onglet réseau de Firebug.
Eg: request http://localhost:8080/myapp/%7B%7Bstylesheet.href%7D%7D, status 404
Lorsque la page est complètement chargée, elle substitue les valeurs du modèle et charge les fichiers css appropriés.
Existe-t-il un moyen d’éviter les erreurs 404 et de le charger après le traitement de angularjs?
J'ai créé un service AngularJS pour utiliser facilement la solution @Artem.
J'ai créé un exemple très simple montrant comment créer un ajout css conditionnel
<link rel="stylesheet" ng-if="lang_direction == 'rtl'" ng-href="{{lang_direction == 'rtl' ? 'css/rtl.css' : ''}}" >
Il existe une autre option utilisant $ route.resolve et ses promesses. Cela attendra que le CSS soit réellement chargé et non seulement ajouté à la tête (après cela, le navigateur commence simplement à récupérer le fichier et, en fonction de la taille du CSS, peut provoquer le refoulement de la page).
// Routing setup
.config(function ($routeProvider) {
$routeProvider
.when('/home', {
controller: 'homeCtrl',
templateUrl: 'home.tpl.html'
}).when('/users', {
controller: 'usersCtrl',
controllerAs: 'vm',
templateUrl: 'users.tpl.html',
resolve: {
load: ['injectCSS', function (injectCSS) {
return injectCSS.set("users", "users.css");
}]
}
}).otherwise({
// default page
redirectTo: '/home'
});
})
Mise en service
.factory("injectCSS", ['$q', '$http', 'MeasurementsService', function($q, $http, MeasurementsService){
var injectCSS = {};
var createLink = function(id, url) {
var link = document.createElement('link');
link.id = id;
link.rel = "stylesheet";
link.type = "text/css";
link.href = url;
return link;
}
var checkLoaded = function (url, deferred, tries) {
for (var i in document.styleSheets) {
var href = document.styleSheets[i].href || "";
if (href.split("/").slice(-1).join() === url) {
deferred.resolve();
return;
}
}
tries++;
setTimeout(function(){checkLoaded(url, deferred, tries);}, 50);
};
injectCSS.set = function(id, url){
var tries = 0,
deferred = $q.defer(),
link;
if(!angular.element('link#' + id).length) {
link = createLink(id, url);
link.onload = deferred.resolve;
angular.element('head').append(link);
}
checkLoaded(url, deferred, tries);
return deferred.promise;
};
return injectCSS;
}])
Vous pouvez ajouter un délai d'attente en utilisant try si vous souhaitez l'inclure.
Consultez ce post pour plus de détails: https://medium.com/angularjs-meetup-south-london/angular-dynamically-injecting-css-file-using-route-resolve-and-promises-7bfcb8ccd05b
C’est ce que j’ai utilisé pour créer des CSS vraiment dynamiques au moment de l’exécution avec AngularJS.
index.html
<head> <style type="text/css" ng-bind-html="styles"></style> </head>
cssService
this.$rootScope.myStyles = ".test { color : red; }";
Ceci est juste un exemple, il peut être préférable de mettre les styles dans un indexController si vous en avez un et de le garder en dehors du $rootScope