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

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

问题描述

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



链接元素在视图/部分的html在顶部,但我被告知这是坏的做法,即使所有现代浏览器支持它,但我可以看到为什么它皱眉了。



另一种可能性是在我的index.html的 head 中放置单独的样式表,但我希望它只加载样式表,如果它的视图是以性能名称。



这是不好的做法,因为样式不会生效,直到css从服务器加载后,导致快速浏览器中的未格式化的内容快速闪烁?我还没见过这个,虽然我在本地测试。



有没有办法通过传递给Angular的 $ routeProvider.when



提前感谢!

解决方案

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


更新1:发布此答案后,我将所有代码添加到一个简单的服务已发布到GitHub。该库位于此处。欢迎随时查看详情。



更新2:如果您需要的只是一个轻量级解决方案样式表为您的路线。如果您想要更全面的解决方案来管理应用程序中的按需样式表,则可以尝试 Door3的AngularCSS项目。它提供了更多细粒度的功能。


如果将来的任何人都感兴趣,下面是我想出的: p>

1。为< head> 元素创建自定义指令:

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

此指令执行以下操作:


  1. 编译(使用 $ compile )一个html字符串,为 scope.routeStyles < link /> c $ c>对象使用 ng-repeat ng-href

  2. 它将< link /> 的编译集附加到< head> li>
  3. 然后使用 $ rootScope 来监听'$ routeChangeStart'事件。对于每个'$ routeChangeStart'事件,它抓取当前 $$路由对象即将离开),并从< head> 标签中删除其部分特定的css文件。它还抓住next $$ route 对象(用户要转到的路由),并将其任何部分特定的css文件添加到< head> 标签。

  4. ng-repeat 编译的< link /> 标记处理所有添加和删除页面特定的样式表,基于添加或删除 scope.routeStyles 对象。

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

  app.config(['$ routeProvider',function($ routeProvider){
$ routeProvider
.when('/ some / route / 1',{
templateUrl:'partials /partial1.html',
controller:'Partial1Ctrl',
css:'css / partial1.css'
})
.when('/ some / route / ,{
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 属性用于设置每个页面路由的对象。该对象被传递给'$ routeChangeStart'事件。$$ route 。因此,当侦听'$ routeChangeStart'事件时,我们可以抓取我们指定的 css 属性,并追加/那些< link /> 标记。请注意,在路由上指定 css 属性是完全可选的,因为它从'/ some / route / 2' example。如果路由没有 css 属性,则< head> 指令将不会对该路由。还要注意,你甚至可以在每个路由上有多个页面特定的样式表,如上面的'/ some / route / 3'示例,其中 css 属性是该路由所需的样式表的相对路径数组。



3。完成
这两个东西设置了所有需要的东西,并且在我看来,它使用最干净的代码。



希望帮助别人,像我一样在这个问题上挣扎。


What is the proper/accepted way to use separate stylesheets for the various views my application uses?

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.

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.

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.

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

Thanks in advance!

解决方案

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.

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.

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

This directive does the following things:

  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.

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

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. 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天全站免登陆