【问题标题】:How to append a stylesheet to <head> in AngularJS $routeProvider?如何在 AngularJS $routeProvider 中将样式表附加到 <head>?
【发布时间】:2013-08-31 16:51:46
【问题描述】:

我只想在用户访问我的 AngularJS 应用程序/网站上的 contact.html 视图时加载特定的 CSS 文件。我发现这个答案对我来说几乎是有意义的How to include view/partial specific styling in AngularJS charlietfl 接受的答案是:

可以在$routeProvider 的头部附加一个新样式表。为了 使用字符串很简单,但也可以创建新的链接元素, 或为样式表创建服务

/* check if already exists first - note ID used on link element*/
/* could also track within scope object*/
if( !angular.element('link#myViewName').length){
    angular.element('head').append('<link id="myViewName" href="myViewName.css" rel="stylesheet">');
}

在页面中预加载的最大好处是任何背景图片都会 已经存在,并且FOUC的可能性较小

问题是我不知道在我的$routeProvider 中的确切位置添加代码。 charlietfl 在评论中提到了将其放在何处,内容为

如果没有调用路由的时间,则不会。可以把这段代码放进去 在 routeProvider 内的控制器回调,或者可能 在可能更早触发的解析回调中

我已按照建议修改了我的$routeProvider。我在.when('/contact' 之后的对象中添加了resolve。这是我的代码

angular.module('maxmythicApp', ['ngResponsiveImages'])
  .config(function ($locationProvider, $routeProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix = '!';
    $routeProvider
      .when('/', {
        templateUrl: '/views/design.html',
        controller: 'MainCtrl'
      })
      .when('/design', {
        templateUrl: '/views/design.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: '/views/about.html',
        controller: 'MainCtrl'
      })
      .when('/contact', {
        templateUrl: '/views/contact.html',
        controller: 'MainCtrl',
        resolve: 
          if( !angular.element('link#myViewName').length){
            angular.element('head').append('<link id="myViewName" href="myViewName.css" rel="stylesheet">');
          }
      })
      .otherwise({
        redirectTo: '/'
      });
  });

这行得通吗?

【问题讨论】:

  • 你必须使用 `$compile' 让 Angular 知道你必须向 dom 添加一些东西。这应该会自动调用 $scope.$apply(),而后者又会调用 $$digest。这应该可以解决问题。
  • 我应该把$compile放在哪里?

标签: css angularjs conditional route-provider


【解决方案1】:

我为它做了服务。

代码的重要部分:

var head = angular.element(document.querySelector('head')); // TO make the code IE < 8 compatible, include jQuery in your page and replace "angular.element(document.querySelector('head'))" by "angular.element('head')"

if(head.scope().injectedStylesheets === undefined)
{
    head.scope().injectedStylesheets = [];
    head.append($compile("<link data-ng-repeat='stylesheet in injectedStylesheets' data-ng-href='{{stylesheet.href}}' rel='stylesheet' />")(scope)); // Found here : http://stackoverflow.com/a/11913182/1662766
}

head.scope().injectedStylesheets.push({href: "/url/to/style.css"});

Github 中的完整代码:https://github.com/Yappli/angular-css-injector)

【讨论】:

    【解决方案2】:

    已更新Here is the solution to inject(load) a specific CSS using the $routeProvider

    下面描述的解决方案是一种替代方案,可以根据可以在其他情况下使用的路由应用不同的类和页面标题。

    对于每条路线,我都创建了一个名为“bodyClass”和“title”的新键(但你可以调用任何你喜欢的名称),它看起来像这样:

    'use strict';
    var myApp = angular.module('myApp', 'ngResource'])
    .config(function ($routeProvider) {
    
    myApp.siteName = 'My Cool App';
    
    $routeProvider
        .when('/home', {
         title:'Home - ' + myApp.siteName,
         bodyClass: 'home',
         templateUrl: 'views/home.html',
         controler: 'bmsHomeCtrl'
        })
        .when('/contact', {
          title:'Contact - ' + myApp.siteName,
          bodyClass: 'contact',
          templateUrl: 'views/contact.html',
          controler: 'bmsContactCtrl'
        })
        .otherwise({
          redirectTo: '/home'
        });
    });
    

    然后对于每个 $routeChangeSuccess 事件,我更改页面的 &lt;title&gt; 以及 &lt;body&gt; 的类。

    myApp.run(['$location', '$rootScope', function($location, $rootScope) {
        $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
    
          if (current.$$route) {
    
            $rootScope.title = current.$$route.title;
    
            $rootScope.bodyClass = current.$$route.bodyClass;
          }
        });
    }]);
    

    您将上面的代码放在同一个主 app.js(例如)文件中。

    在呈现视图的 index.html 页面上,我有以下代码来获取标题和类:

    <title>{{ title }}</title>
    
    <body class="{{ bodyClass }}">
    

    所以如果我访问我的应用程序的主页,标题标签将是

    <tittle> Home - My Cool App</tittle>
    

    而body标签将是

    <body class="home">
    

    它就像一个魅力。

    我知道此解决方案不会加载 CSS 文件,但您可以将这些样式放入“.contact”类中,该类仅在您点击具体路线。

    不确定是否能解决您的问题,但我希望对您有所帮助或至少为您指明正确的方向。

    【讨论】:

    • 当请求该资源时,.contact 类中的 css 将与主 css 的其余部分一起加载。它不是动态加载的,而是动态应用的。
    • @AGDM 是正确的。而且我上面描述的也是正确的! :) 也许“加载”这个词有点误导。所以我很高兴将其更改为“已应用”。
    【解决方案3】:

    对于完整的解决方案,我建议使用AngularCSS

    如您所知,在 Angular 中,我们可以在页面和组件中包含模板(结构)和控制器(行为)。 AngularCSS 启用了最后一个缺失的部分:附加样式表(演示文稿)。

    路线示例:

    $routeProvider
    .when('/page1', {
      templateUrl: 'page1/page1.html',
      controller: 'page1Ctrl',
      /* Now you can bind css to routes */
      css: 'page1/page1.css'
    })
    .when('/page2', {
      templateUrl: 'page2/page2.html',
      controller: 'page2Ctrl',
      /* You can also enable features like bust cache, persist and preload */
      css: {
        href: 'page2/page2.css',
        bustCache: true
      }
    })
    .when('/page3', {
      templateUrl: 'page3/page3.html',
      controller: 'page3Ctrl',
      /* This is how you can include multiple stylesheets */
      css: ['page3/page3.css','page3/page3-2.css']
    })
    .when('/page4', {
      templateUrl: 'page4/page4.html',
      controller: 'page4Ctrl',
      css: [
        {
          href: 'page4/page4.css',
          persist: true
        }, {
          href: 'page4/page4.mobile.css',
          /* Media Query support via window.matchMedia API
           * This will only add the stylesheet if the breakpoint matches */
          media: 'screen and (max-width : 768px)'
        }, {
          href: 'page4/page4.print.css',
          media: 'print'
        }
      ]
    });
    

    指令示例:

    myApp.directive('myDirective', function () {
      return {
        restrict: 'E',
        templateUrl: 'my-directive/my-directive.html',
        css: 'my-directive/my-directive.css'
      }
    });
    

    你可以阅读更多关于 AngularCSS here:

    http://door3.com/insights/introducing-angularcss-css-demand-angularjs

    【讨论】:

      【解决方案4】:

      我认为最好/最简单的答案是我留下的here。有人问了同样的问题,所以我想出了一些简单的代码和一个小的 github repo 来处理这种情况。

      【讨论】:

        猜你喜欢
        • 2012-08-03
        • 2012-10-19
        • 1970-01-01
        • 2016-10-18
        • 2019-08-26
        • 2014-02-02
        • 2010-10-12
        • 1970-01-01
        相关资源
        最近更新 更多