Conditionally-rendering css in html head

后端 未结 5 1837
忘了有多久
忘了有多久 2020-12-05 19:18

I am trying to dynamically add css to my html head using angular js. Here is sample code

相关标签:
5条回答
  • 2020-12-05 19:22

    You should use ng-href instead of href.

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

    Example

    0 讨论(0)
  • 2020-12-05 19:25

    I made a AngularJS service to use easily the @Artem solution.

    It's here on GitHub.

    0 讨论(0)
  • 2020-12-05 19:26

    For anyone wishing to create truly dynamic CSS at runtime with AngularJS this is what I used.

    index.html

    <head> <style type="text/css" ng-bind-html="styles"></style> </head>

    cssService

    this.$rootScope.myStyles = ".test { color : red; }";

    This is just an example, it may be better for you to put the styles into an indexController if you have one and keep it off the $rootScope

    0 讨论(0)
  • 2020-12-05 19:29

    I've created a very simple example of how make a conditionaly css addition

    <link rel="stylesheet" ng-if="lang_direction == 'rtl'" ng-href="{{lang_direction == 'rtl' ? 'css/rtl.css' : ''}}" >
    
    0 讨论(0)
  • 2020-12-05 19:41

    There's a another option using $route.resolve and promises. This will wait until the CSS is actually loaded not only added to the head (after that the browser just starts retrieving the file and depending on CSS size can cause page reflow).

    // 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'
      });
    })
    

    Service implementation

    .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;
    }])
    

    You could add a timeout using tries if this is something you would like to include.

    Check out this post for more details:https://medium.com/angularjs-meetup-south-london/angular-dynamically-injecting-css-file-using-route-resolve-and-promises-7bfcb8ccd05b

    0 讨论(0)
提交回复
热议问题