Filippo oretti
Filippo oretti

Reputation: 49873

AngularJS observe directive attribute expressions, inherit scope dynamically

My code is as simple:

.controller('Ctrl', ['$scope', '$timeout', function ($scope, $timeout) {
    $timeout(function () {
      $scope.x = 5;
    }, 2000);
  }])
.directive('ngHey', ['$parse', function ($parse) {
    return {
      'restrict': 'A',
      'scope': true,
      'link': function($scope, el, atr) {

        var go = function () {
            if ($parse(atr.ngHey)()) {

              alert('oiiiiiii');
            }
          };

        atr.$observe('ngHey', function (val) {
          if (val) {

            go();
          }
        });
      }
    };
  }]);

//view.html

<div ng-controller="Ctrl">
<span ng-hey="x > 3"></span>
</div>

I would like to be able to fire when directive expression changes and when it's true or false, but at the moment the alert never happen...

It works only if i do something like:

<div ng-controller="Ctrl">
    <span ng-hey="{{x > 3}}"></span>
    </div>

which is not what i would like, i would like the directive to execute expressions as for ng-if or ng-hide etc...

Any tip or help appreciated, thanks

Upvotes: 3

Views: 778

Answers (2)

dfsq
dfsq

Reputation: 193301

You can't use $observe in this case, as it Observes an interpolated attribute. (documentation). In this case you can use $watch on the scope like this:

.directive('ngHey', ['$parse',
    function($parse) {
        return {
            scope: true,
            link: function($scope, el, atr) {

                var go = function(value) {
                    if (value) {
                        alert('oiiiiiii');
                    }
                };

                $scope.$watch(atr.ngHey, function(val) {
                    if (val) {
                        go(val);
                    }
                });
            }
        };
    }
]);

Demo: http://plnkr.co/edit/XakjA2I7lpJdo9YAZFEH?p=preview

UPD. Based on the OP's comments, updated directive looks like:

.directive('ngHey', ['$parse',
    function($parse) {
        return {
            scope:{ngHey: '='},
            link: function($scope, el, atr) {

                var go = function(value) {
                    if ($scope.ngHey) {
                        alert('oiiiiiii');
                    }
                };

                $scope.$watch('ngHey', function(val) {
                    if (val) {
                        go();
                    }
                });
            }
        };
    }
]);

Note, how you can use $scope.ngHey in this case, not need to $eval attribute.

Demo: http://plnkr.co/edit/XakjA2I7lpJdo9YAZFEH?p=preview

Upvotes: 3

mohamedrias
mohamedrias

Reputation: 18576

JSFIDDLE DEMO

As the $timeout is setting the value of x later, the condition inside the directive checking for attribute was returning false always. So use $watch to check the condition in go() whenever x changes.

var myApp = angular.module('myApp',[]);

myApp.directive('ngHey', function () {
    return {
      'restrict': 'A',
       'scope': true,
      'link': function($scope, el, attr) {

        var go = function () {
            if ($scope.$eval(attr.ngHey)) {
              alert('oiiiiiii');
            }
          };

        $scope.$watch('x', function (val) {
          if (val) {
            go();
          }
        });
      }
    };
  });

Instead of $parse use $scope.$eval and also similarly instead of $observe use $watch.

Upvotes: 1

Related Questions