3

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

4
  • scope.$eval(atr.ngHey) Commented Mar 3, 2015 at 11:30
  • @mohamedrias tried, just replaced $scope.$eval(atr.ngHey)(); on $parse(atr.ngHey); but it seems not firing when expression becomes true Commented Mar 3, 2015 at 11:41
  • I've updated in answer. Please check there :) Commented Mar 3, 2015 at 11:49
  • @mohamedrias checked i appreciated but $watch means static variables, i need scope vars to be dynamic Commented Mar 3, 2015 at 13:12

2 Answers 2

3

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

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

5 Comments

hi, i think i fixed all, and yeah you are right for me, i used watch instead of observe and then replaced $parse with $scope.$parent.$eval(atr.ngHey)
if you would add also my changes to your answer i will accept , thank you
oh and i forgot instead of scope:true i added scope:{ngHey:'='}
You don't really need $scope.$parent.$eval(atr.ngHey) if you have scope:{ngHey:'='}. You can simply use $scope.ngHey it will be the same but cleaner.
Check updated answer for new version of the directive.
1

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.

1 Comment

Sorry but i can't use $watch, scope variables are dynamic/unknown, is not always scope.x it could be whatever you want/need :)

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.