CSS 如何将样式表附加到 AngularJS $routeProvider 中的 <head>?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18490882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 00:09:27  来源:igfitidea点击:

How to append a stylesheet to <head> in AngularJS $routeProvider?

cssangularjsconditionalroute-provider

提问by Gabriel

I want to load a specific CSS file only when a user accesses the contact.htmlview on my AngularJS app/site. I found this answer which almost made sense to me How to include view/partial specific styling in AngularJSThe accepted answer by charlietfl reads :

我只想在用户访问contact.html我的 AngularJS 应用程序/站点上的视图时加载特定的 CSS 文件。我发现这个答案对我来说几乎是有意义的如何在 AngularJS 中包含视图/部分特定样式charlietfl 接受的答案是:

Could append a new stylesheet to head within $routeProvider. For simplicity am using a string but could create new link element also, or create a service for stylesheets

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

Biggest benefit of prelaoding in page is any background images will already exist, and less lieklyhood of FOUC

可以附加一个新的样式表到 head 内$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

The problem is that I do not know exactly where in my $routeProviderto add the code. charlietfl mentions where to put it in a comment which reads

问题是我不知道在我的哪里$routeProvider添加代码。charlietfl 在评论中提到了把它放在哪里

not if the when for the route hasn't been called. Can put this code in controller callback of when within the routeProvider, or perhaps within resolve callback which likely triggers sooner

如果尚未调用路线的时间,则不会。可以将此代码放在 routeProvider 中的控制器回调中,或者可能在可能会更快触发的解析回调中

I have modified my $routeProviderfollowing the advice. I added a resolvein the object following .when('/contact'. Here is my code

我已经修改了我$routeProvider的建议。我resolve在下面的对象中添加了一个.when('/contact'。这是我的代码

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

Would this work?

这行得通吗?

回答by Gabriel

I made a service for it.

我为它做了一个服务。

Important part of the code :

代码的重要部分:

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"});

Full code in Github : https://github.com/Yappli/angular-css-injector)

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

回答by Denison Luz

UPDATED: Here is the solution to inject(load) a specific CSS using the $routeProvider.

更新这是使用 $routeProvider 注入(加载)特定 CSS 的解决方案

The solution described below is an alternative to apply different classes and page title based on the route which could be used in other situations.

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

For each route I've created a new key called 'bodyClass' and 'title' (but you could called anything you like it) and it looks like this:

对于每条路线,我都创建了一个名为“ 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'
    });
});

Then for each $routeChangeSuccess event I change the <title>of the page and also the class of the <body>.

然后对于每个 $routeChangeSuccess 事件,我更改<title>页面的<body>.

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

You put the code above on the same main app.js(for example) file.

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

On my index.html page, which renders the views, I have the following codes to pick up the title and class:

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

<title>{{ title }}</title>

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

So if i visit the home page of my application the title tag will be

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

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

and the body tag will be

身体标签将是

<body class="home">

It's working like a charm.

它就像一个魅力。

I know this solution doesn't load a CSS file, but you could put those styles inside a '.contact' class that is appliedonly when you hit a specific route.

我知道这个解决方案不加载CSS文件,但你可以把这些样式的“内。接触是”类应用,当你点击一个特定的路线而已。

Not sure if solves your problem but I hope that helps or at least point you on the right direction.

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

回答by castillo.io

For a full solution I suggest using AngularCSS.

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

As you already know, in Angular we can include templates (structure) and controllers (behavior) in pages and components. AngularCSS enables the last missing piece: attaching stylesheets (presentation).

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

Routes example:

路线示例:

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

Directive example:

指令示例:

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

You can read more about AngularCSS here:

您可以在此处阅读有关 AngularCSS 的更多信息:

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

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

回答by tennisgent

I think the best/simplest answer is one I left here. Someone else asked the same question, so I came up with some simple code and a small github repo to handle this scenario.

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