web-dev-qa-db-fra.com

CSS rendu rendu dans la tête html

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?

18
Raja

Vous devriez utiliser ng-href au lieu de href.

<link ng-repeat="stylesheet in stylesheets" ng-href="{{stylesheet.href}}" type="{{stylesheet.type}}" rel="stylesheet" />

Exemple

31
Artem Andreev

J'ai créé un service AngularJS pour utiliser facilement la solution @Artem.

C'est ici sur GitHub .

7
Gabriel

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' : ''}}" >
2
Michael Kisilenko

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

2
Gerard Sans

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

0
Chris