Isolate scope
The problem is that ng-show
uses the scope of the element it's on. If it's on an element that has a directive with isolate scope, then it will use that isolate scope, and not have access to the outside scope.
In this particular case, I suspect that description-popup
has isolate scope, which means ng-show only has access to the scope of that directive, which probably doesn't have the item
that you're trying to test against.
What is isolate scope?
Isolate scope means the directive has its own scope that does not inherit from the surrounding scope. Normal scopes inherit from the surrounding scopes, so they have access to the data on that surrounding scope. Isolate scope does not.
Why would anyone ever want to use isolate scope?!
Reuse. If a directive is intended to be reused in lots of places, in lots of different scopes with a variety of properties on them, you don't want properties on the directive's scope to collide with the properties of the surrounding scope. And since the directive is supposed to be totally independent and not use the surrounding scope at all, it's often a good idea to give it an isolate scope. There are very few disadvantages to this. Really, the only thing that's likely to go wrong is when someone wants to put an ng-show
or ng-hide
on that element.
Solution
Put your ng-show
on an extra <div>
around the description-popup
:
<div ng-show="!!item.description && item.show_description">
<div class="description-popup"
style="left: {{item.x}}px; top: {{item.y}}px">
<h2>{{item.label}}</h2>
<p>{{item.description}}</p>
<p>{{!!item.description && item.show_description}}</p>
</div>
</div>
This assuming that the behaviour in this JSFiddle is what you want.
This is probably only true for versions of Angular < 1.2. In 1.2, the behaviour of isolate scopes seems to have been cleaned up: https://docs.angularjs.org/guide/migration#isolate-scope-only-exposed-to-directives-with-scope-property