如何在 AngularJS 中包含视图/部分特定样式 [英] How to include view/partial specific styling in AngularJS

查看:23
本文介绍了如何在 AngularJS 中包含视图/部分特定样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为我的应用程序使用的各种视图使用单独的样式表的正确/可接受的方法是什么?

目前我在顶部的视图/部分的 html 中放置了一个链接元素,但我被告知这是不好的做法,即使所有现代浏览器都支持它,但我明白为什么它不受欢迎.

Currently I'm placing a link element in the view/partial's html at the top but I've been told this is bad practice even though all modern browsers support it but I can see why it's frowned upon.

另一种可能性是将单独的样式表放在我的 index.html 的 head 中,但我希望它仅在以性能的名义加载视图时才加载样式表.

The other possibility is placing the separate stylesheets in my index.html's head but I would like it to only load the stylesheet if its view is being loaded in the name of performance.

这是不好的做法,因为样式在从服务器加载 css 后才会生效,导致在慢速浏览器中快速闪烁未格式化的内容?虽然我正在本地测试,但我还没有见证这一点.

Is this bad practice since styling won't take effect until after the css is loaded form the server, leading to a quick flash of unformatted content in a slow browser? I have yet to witness this although I'm testing it locally.

有没有办法通过传递给Angular的$routeProvider.when的对象来加载CSS?

Is there a way to load the CSS through the object passed to Angular's $routeProvider.when?

提前致谢!

推荐答案

我知道这个问题现在很老了,但是在对这个问题的各种解决方案做了大量研究之后,我想我可能想出了一个更好的解决方案.

I know this question is old now, but after doing a ton of research on various solutions to this problem, I think I may have come up with a better solution.

更新 1: 自从发布此答案后,我已将所有这些代码添加到已发布到 GitHub 的简单服务中.该存储库位于此处.请随时查看以获取更多信息.

UPDATE 1: Since posting this answer, I have added all of this code to a simple service that I have posted to GitHub. The repo is located here. Feel free to check it out for more info.

更新 2: 如果您只需要一个轻量级的解决方案来为您的路线拉入样式表,那么这个答案就很好.如果您想要一个更完整的解决方案来管理整个应用程序中的按需样式表,您可能需要查看 Door3 的 AngularCSS 项目.它提供了更细粒度的功能.

UPDATE 2: This answer is great if all you need is a lightweight solution for pulling in stylesheets for your routes. If you want a more complete solution for managing on-demand stylesheets throughout your application, you may want to checkout Door3's AngularCSS project. It provides much more fine-grained functionality.

如果将来有人感兴趣,这是我想出的:

In case anyone in the future is interested, here's what I came up with:

1.为 元素创建自定义指令:

1. Create a custom directive for the <head> element:

app.directive('head', ['$rootScope','$compile',
    function($rootScope, $compile){
        return {
            restrict: 'E',
            link: function(scope, elem){
                var html = '<link rel="stylesheet" ng-repeat="(routeCtrl, cssUrl) in routeStyles" ng-href="{{cssUrl}}" />';
                elem.append($compile(html)(scope));
                scope.routeStyles = {};
                $rootScope.$on('$routeChangeStart', function (e, next, current) {
                    if(current && current.$$route && current.$$route.css){
                        if(!angular.isArray(current.$$route.css)){
                            current.$$route.css = [current.$$route.css];
                        }
                        angular.forEach(current.$$route.css, function(sheet){
                            delete scope.routeStyles[sheet];
                        });
                    }
                    if(next && next.$$route && next.$$route.css){
                        if(!angular.isArray(next.$$route.css)){
                            next.$$route.css = [next.$$route.css];
                        }
                        angular.forEach(next.$$route.css, function(sheet){
                            scope.routeStyles[sheet] = sheet;
                        });
                    }
                });
            }
        };
    }
]);

该指令执行以下操作:

  1. 它编译(使用$compile)一个html 字符串,使用 ng-repeat<link/>scope.routeStyles 对象中的每个项目创建一组标签代码>ng-href.
  2. 它将编译后的 元素附加到 标签.
  3. 然后使用 $rootScope 来监听 '$routeChangeStart' 事件.对于每个 '$routeChangeStart' 事件,它会抓取current"$$route 对象(用户即将离开的路径)并从 标签中删除其部分特定的 css 文件.它还抓住了下一个"$$route 对象(用户将要前往的路径)并将其任何特定于部分的 css 文件添加到 标记.
  4. 编译后的 <link/> 标记的 ng-repeat 部分根据获取的内容处理所有页面特定样式表的添加和删除在 scope.routeStyles 对象中添加或删除.
  1. It compiles (using $compile) an html string that creates a set of <link /> tags for every item in the scope.routeStyles object using ng-repeat and ng-href.
  2. It appends that compiled set of <link /> elements to the <head> tag.
  3. It then uses the $rootScope to listen for '$routeChangeStart' events. For every '$routeChangeStart' event, it grabs the "current" $$route object (the route that the user is about to leave) and removes its partial-specific css file(s) from the <head> tag. It also grabs the "next" $$route object (the route that the user is about to go to) and adds any of its partial-specific css file(s) to the <head> tag.
  4. And the ng-repeat part of the compiled <link /> tag handles all of the adding and removing of the page-specific stylesheets based on what gets added to or removed from the scope.routeStyles object.

注意: 这要求您的 ng-app 属性在 元素上,而不是在 元素上> 内的任何内容.

Note: this requires that your ng-app attribute is on the <html> element, not on <body> or anything inside of <html>.

2.使用 $routeProvider 指定哪些样式表属于哪些路由:

2. Specify which stylesheets belong to which routes using the $routeProvider:

app.config(['$routeProvider', function($routeProvider){
    $routeProvider
        .when('/some/route/1', {
            templateUrl: 'partials/partial1.html', 
            controller: 'Partial1Ctrl',
            css: 'css/partial1.css'
        })
        .when('/some/route/2', {
            templateUrl: 'partials/partial2.html',
            controller: 'Partial2Ctrl'
        })
        .when('/some/route/3', {
            templateUrl: 'partials/partial3.html',
            controller: 'Partial3Ctrl',
            css: ['css/partial3_1.css','css/partial3_2.css']
        })
}]);

此配置将自定义 css 属性添加到用于设置每个页面路由的对象.该对象作为 .$$route 传递给每个 '$routeChangeStart' 事件.所以当监听 '$routeChangeStart' 事件时,我们可以抓取我们指定的 css 属性并附加/删除那些 代码> 根据需要标记.请注意,在路由上指定 css 属性是完全可选的,因为它在 '/some/route/2' 示例中被省略了.如果路由没有 css 属性, 指令将不会对该路由执行任何操作.另请注意,您甚至可以为每个路由设置多个特定于页面的样式表,如上面的 '/some/route/3' 示例中所示,其中 css 属性是一个数组该路由所需的样式表的相对路径.

This config adds a custom css property to the object that is used to setup each page's route. That object gets passed to each '$routeChangeStart' event as .$$route. So when listening to the '$routeChangeStart' event, we can grab the css property that we specified and append/remove those <link /> tags as needed. Note that specifying a css property on the route is completely optional, as it was omitted from the '/some/route/2' example. If the route doesn't have a css property, the <head> directive will simply do nothing for that route. Note also that you can even have multiple page-specific stylesheets per route, as in the '/some/route/3' example above, where the css property is an array of relative paths to the stylesheets needed for that route.

3.大功告成这两件事设置了所需的一切,在我看来,它以最简洁的代码完成.

3. You're done Those two things setup everything that was needed and it does it, in my opinion, with the cleanest code possible.

希望能帮助那些可能和我一样在这个问题上挣扎的人.

Hope that helps someone else who might be struggling with this issue as much as I was.

这篇关于如何在 AngularJS 中包含视图/部分特定样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆