Reputation: 55604
I'm writing an Angular directive to display some information about a music album, currently it shows the information below the album art, but if the element gets too small then it should shrink the album art and put the information next to it. At the moment I just have the html in the page directly and have css to do the changes in the main page, but this causes the page to be quite monolithic as it also display other things, which is why I want to seperate it out into directives.
However I can't see how to include CSS in the directive, I don't want to include it inline in the html, and I could put a style tag in the html and put it in there, but then it would be repeated every time I use the directive. Is there some way of injecting a link to a CSS file into the head from the directive? Like there is a templateUrl field is there a stylesheetUrl or something?
Upvotes: 4
Views: 567
Reputation: 19138
Structuring an angular app is one of the hardest things about learning angular. Angular tries hard to modularise code, but (the current state of) html, css, and javascript doesn't really allow you to package the things together, so you have to find a way that works well for you.
The way I keep things separate (yet together) is generally using my build system (I use gulp), and a CSS preprocessor (for me, Stylus).
My process for creating a new directive is as follows:
Define a new angular module (in its own file) my-albums.coffee
:
angular.module('my-albums', [])
.directive('myAlbumDirective', ()->
restrict: 'A'
templateUrl: 'SomeTemplate.jade'
# etc.
)
Create a jade template my-album-directive.jade
.album
img(ng-src="{{album.imageUrl}})
span.name {{album.name}}
Create the stylus file with the same name as the module prefixed with an underscore: _my-albums.styl
. In here I will include module specific css.
[myAlbumDirective]
.album
display flex
flex-direction column
@media screen and (min-width: 600px)
flex-direction row
Then, whenever I import an angular module into my app.coffee
(which contains a long list of module imports), I also import its style in my main.styl
stylesheet:
@import '../my-albums/_my-albums.styl'
When I run my build system, it (among other things):
.jade
files into a app.templates
angular module (pre-populating the $templateCache
(app.templates
is included in the imports in app.coffee
script.js
style.css
Then inside my index page I just have two imports:
script(src='js/app.js')
link(rel='stylesheet', href='css/style.css')
TL;DR:
There's no easy way of keeping your directive code separate from the rest of the page, but if you research build systems and other people's angular project structures, you'll find something you like.
Note SoonTM things will be neater (see web components and angular 2.0)
Upvotes: 0
Reputation: 13079
You can inject css in your directive like this:
var head = document.getElementsByTagName('head')[0];
var cs = document.createElement('link');
cs.rel = 'stylesheet';
cs.href = 'css/myStylesheet.css';
head.appendChild(cs);
So a directive would look like this:
app.directive('myDirective', function () {
var head = document.getElementsByTagName('head')[0];
var cs = document.createElement('link');
cs.rel = 'stylesheet';
cs.href = 'css/myStylesheet.css';
head.appendChild(cs);
return {
templateUrl:'templates/myTemplate.html',
link: function (scope, elm, attrs, ctrl) {
}
};
});
Upvotes: 0
Reputation: 17721
You could check this module: angular-css-injector.
Be warned it's currently only compatible with angular 1.2.x...
Upvotes: 1