19

I'm trying to apply the ng-style attribute on a custom directive tag, kind of like so:

<my-directive ng-style="myStyle"></my-directive>

Inside the controller I have:

$scope.myStyle = {
    "background": "red"
}

This doesn't seem to work though. When I inspect the HTML 'MyStyle' does not get rendered. When I apply the same ng-style tag on a regular div it does render properly.

Why doesn't ng-style work on custom directive tags?

Alex Osborn
  • 9,831
  • 3
  • 33
  • 44
sthomps
  • 4,480
  • 7
  • 35
  • 54

1 Answers1

33

Your directive likely defines an isolate scope: scope: { ... }. In that case, all directives defined on that element will use the isolate scope. Therefore, ng-style will look for property myStyle on the isolate scope, which doesn't exist.

enter image description here

Above, gray lines show $parents, dashed lines show prototypal inheritance. Scope 004 is your isolate scope. Scope 003 is your controller scope. ng-style will look for myStyle in scope 004, not find it, then it will follow the dashed line and look for it in Scope, and not find it there either.

Normally you don't want to use directives that create an isolate scope along with other directives on the same element. You have a few options:

  1. use scope: true instead of an isolate scope in your directive. Then when ng-style looks for myStyle in scope 004 and doesn't find it, it will then follow the dashed line (in the picture below) and find it in the parent scope:
    enter image description here
  2. use ng-style="$parent.myStyle" in your HTML to access the myStyle property in the parent scope (i.e., follow the gray line in the first picture).
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • 2
    What a thorough answer. Very nice! – Josh David Miller Mar 15 '13 at 04:06
  • 1
    Mark, if you're not preparing a book about Angular, than you should. – Stewie Mar 15 '13 at 08:35
  • 1
    Your hunch was exactly the issue I was facing. Thanks for such a detailed answer. Now I just need to figure out which solution is the best for me. My directive represents a reusable 'widget' and my understanding is that it is good practice for such directives to have isolated scope. I'm also considering wrapping my directive in a div and applying the ng-style to this div. – sthomps Mar 16 '13 at 22:58
  • 1
    @sthomps, [this answer](http://stackoverflow.com/a/14914798/215945) by Josh might help you decide which kind of scope is appropriate for your directive. – Mark Rajcok Mar 16 '13 at 23:22
  • Is there a good solution if I want the directive's style method to be called, without interfacing to the controller? – Peter Ehrlich Nov 29 '13 at 21:57