4

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?

3
  • That's sadly a common problem. Commented Dec 2, 2014 at 10:53
  • Why do you need the CSS inside the directive? Is this so that you can package the directive and use it in other projects? Commented Dec 2, 2014 at 11:01
  • @EdHinchliffe, just to keep everything seperate? ideally I'd like to specify the CSS in it's own file, and then have the server combine the CSS of all the directives (even more preferably just the ones used on the page) into one file and just serve that. Commented Dec 2, 2014 at 11:06

3 Answers 3

1

You could check this module: angular-css-injector.
Be warned it's currently only compatible with angular 1.2.x...

Sign up to request clarification or add additional context in comments.

Comments

0

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) {

        }
    };
});

Comments

0

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:

  1. Define a new angular module (in its own file) my-albums.coffee:

    angular.module('my-albums', [])
    
    .directive('myAlbumDirective', ()->
      restrict: 'A'
      templateUrl: 'SomeTemplate.jade'
      # etc.
    )
    
  2. Create a jade template my-album-directive.jade

    .album
      img(ng-src="{{album.imageUrl}})
      span.name {{album.name}}
    
  3. 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):

  • Automatically compiles .jade files into a app.templates angular module (pre-populating the $templateCache (app.templates is included in the imports in app.coffee
  • Compiles and concatenates all coffeescript into script.js
  • Compiles and concatenates all stylus files whose filenames do not begin with an underscore into 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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.