Aminadav Glickshtein
Aminadav Glickshtein

Reputation: 24590

Why i cannot use ng-show inside directive in AngularJS?

I am trying to make an element that show it's content when clicking on it: There are many ways to do it. I want to do it inside directive. Why is it not working?

http://plnkr.co/edit/Y13bcD7Ikuk6pERM9Mm8?p=preview

HTML:

<ez-option title="option 1">
        Option 1 inside
        <input ng-model="x">{{x}}
    </ez-option>
    <ez-option title="option 2">
        Option 2 inside
   </ez-option>

JavaScript:

directive('ezOption',function(){
    return {
        template:'<li></li><div ng-show=selected ng-transclude class=body></div>',
        link:function ($scope,iElement,iAttrs,controller,tanscludeFn){
            iElement.find('li').html(iAttrs.title)
            iElement.find('li').on('click',function(){
              $scope.selected=true
            })
        },
        scope:true,
        transclude:true
    }
})

Upvotes: 0

Views: 47

Answers (2)

charlietfl
charlietfl

Reputation: 171679

Since your event is outside of angular ...it is a DOM event, you need to tell angular about the scope changes so it can run a digest.

Use $scope.$apply(). If you use core event directives like ng-click this is done internally by angular.

   iElement.find('li').on('click',function(){
        $scope.selected=true;
        $scope.$apply();
    });

Thus you are generally better off using the multitude of core angular event directives before resorting to your own

DEMO

Upvotes: 1

logee
logee

Reputation: 5067

This is because angular is not aware of the change in scope from your click event. To make it aware, you should do this

            iElement.find('li').on('click',function(){
              $scope.$apply(function() {
                $scope.selected=true;
              })
            })

Alternatively, you can use angular's ng-click instead

m.directive('ezOption',function(){
    return {
        template:'<li ng-click="selected=true"></li><div ng-show=selected ng-transclude class=body></div>',
        link:function ($scope,iElement,iAttrs,controller,tanscludeFn){
            iElement.find('li').html(iAttrs.title);
        },
        controller:function($scope){
          $scope.selected=false
        },
        transclude:true
    }
})

Upvotes: 2

Related Questions