0

Here is the my code

    var directive = {
        restrict: 'E',
        templateUrl: '/static/myTemplate.html',
        scope: {
        },
        controller: ["$scope", controllerFunc],
        controllerAs: 'multiCheckboxCtrl',
        bindToController: true,
        link: linkFunc,

    };

    return directive;


    function controllerFunc($scope) {

        // $watch List

        /**
         * Event handler for searchText change
         */
        $scope.$watch(angular.bind(this, function () {
            return $scope.multiCheckboxCtrl.clickedElsewhere.value;
        }), function (newVal) {
            if (newVal !== undefined && newVal !== "") {
                console.log(newVal);
                console.log("I am here");
            }
        });


    }

    function linkFunc(scope, element, attr){

        // Detect Element Click Logic
        scope.multiCheckboxCtrl.clickedElsewhere = {value: false};

        $document.on('click', function(){
            scope.multiCheckboxCtrl.clickedElsewhere.value = false;
            console.log(scope.multiCheckboxCtrl.clickedElsewhere);
        });

        element.on('click', function(){
            event.stopPropagation();
            scope.multiCheckboxCtrl.clickedElsewhere.value = true;
            console.log(scope.multiCheckboxCtrl.clickedElsewhere);
        });
        // End Detect Element Click Logic

    }

The linkFunc basically determines if the directive element is clicked or not.

I verified that whenever the directive element is clicked it consoles true, and when any element outside directive element is clicked it consoles false.

However it seems like my $watch in the controller is not catching the change.

Can anyone show me what is going wrong

Thanks

1
  • Try add to your event listener functions following scope.$apply(). Like this $document.on('click', function(){ scope.multiCheckboxCtrl.clickedElsewhere.value = false; console.log(scope.multiCheckboxCtrl.clickedElsewhere); scope.$apply() }) Commented Mar 3, 2016 at 4:20

1 Answer 1

2

Angular not know that there was a change object properties in event listener.

As documentation say:

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). Because we are calling into the angular framework we need to perform proper scope life cycle of exception handling, executing watches.

Live example on jsfiddle.

angular.module('ExampleApp', [])
  .controller('ExampleController', function($scope) {
   
  })
  .directive('clickDirective', function() {
    var directive = {
      restrict: 'E',
      template: '<div>click me</div>',
      scope: {},
      controller: ["$scope", controllerFunc],
      controllerAs: 'multiCheckboxCtrl',
      bindToController: true,
      link: linkFunc,

    };

    return directive;


    function controllerFunc($scope) {

      // $watch List

      /**
       * Event handler for searchText change
       */
      $scope.$watch(function() {
        return $scope.multiCheckboxCtrl.clickedElsewhere.value;
      }, function(newVal) {
        if (newVal !== undefined && newVal !== "") {
          console.log(newVal);
          console.log("I am here");
        }
      });


    }

    function linkFunc(scope, element, attr) {

      // Detect Element Click Logic
      scope.multiCheckboxCtrl.clickedElsewhere = {
        value: false
      };

      angular.element(document).on('click', function() {
        scope.multiCheckboxCtrl.clickedElsewhere.value = false;
        console.log(scope.multiCheckboxCtrl.clickedElsewhere);
        scope.$apply();
      });

      element.on('click', function() {
        event.stopPropagation();
        scope.multiCheckboxCtrl.clickedElsewhere.value = true;
        console.log(scope.multiCheckboxCtrl.clickedElsewhere);
        scope.$apply();
      });
      // End Detect Element Click Logic

    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="ExampleApp">
  <div ng-controller="ExampleController" id="ExampleController">
    <click-directive></click-directive>
    <div>
       click elsewhere
    </div>
  </div>
</div>

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

Comments

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.