Подтвердить что ты не робот

Условно-рендеринг css в html-заголовке

Я пытаюсь динамически добавлять css в html-head, используя angular js. Вот пример кода

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

Этот код работает так, как ожидалось, но когда браузер загружает страницу, он пытается извлечь ресурсы css с необработанными шаблонами angularjs, и я вижу "404 не найдена ошибка" на вкладке сети firebug.

Eg: request http://localhost:8080/myapp/%7B%7Bstylesheet.href%7D%7D, status 404

Когда страница полностью загружена, она заменяет значения шаблона и загружает собственно css.

Есть ли способ избежать ошибки 404 и заставить его загружать css после обработки углов?

4b9b3361

Ответ 1

Вместо href вы должны использовать ng-href.

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

Пример

Ответ 2

Я сделал услугу AngularJS, чтобы легко использовать решение @Artem.

Он здесь, на GitHub.

Ответ 3

Есть еще одна опция, использующая $route.resolve и promises. Это будет ждать, пока CSS фактически загрузится не только в голову (после этого браузер только начинает извлекать файл и в зависимости от размера CSS может вызвать переполнение страницы).

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

Реализация службы

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

Вы можете добавить таймаут, используя попытки, если это то, что вы хотели бы включить.

Ознакомьтесь с этим сообщением для получения более подробной информации: https://medium.com/angularjs-meetup-south-london/angular-dynamically-injecting-css-file-using-route-resolve-and-promises-7bfcb8ccd05b

Ответ 4

Я создал очень простой пример того, как сделать условное css дополнение

<link rel="stylesheet" ng-if="lang_direction == 'rtl'" ng-href="{{lang_direction == 'rtl' ? 'css/rtl.css' : ''}}" >

Ответ 5

Для тех, кто хочет создать действительно динамический CSS во время выполнения с помощью AngularJS, это то, что я использовал.

index.html

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

cssService

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

Это просто пример, вам может быть лучше поместить стили в indexController, если у вас его есть, и сохраните его с $rootScope