Search code examples
javascriptangularjsangularjs-directiveangularjs-watchangularjs-digest

$scope.$watch not catching the value modified by directive


My directive give focus to my span and assigns boolean value i.e, focusToSpan to true whenever I press shifttab,however, this change is not reflected in my controller and in the template. I even checked with $scope.$watch on focusToSpan variable as below

Directive

(function() {
    'use strict';
    angular.module("my.page").directive('getFocusToSpan', function() {
        return {
            link: function(scope, elem, attr, ctrl) {
                elem.bind("keydown keypress", function(event) {
                    if (event.which === 16) {
                        $('.iconclass').attr("tabIndex", -1).focus();
                        scope.focusToSpan = true;
                    }
                });
            }
        };

    });

})();

Controller

     $scope.$watch('focusToSpan', function(newValue) {
     if (angular.isDefined(newValue)) {

     alert(newValue);
     }
     });

which is not getting called.May I know how the change made to a controller variable in the directive will be reflected in the controller and in the template. Thanks, Balaji.


Solution

  • Outside angular context you manipulate scope/binding that doesn't get updated. For making binding updated you need to run digest cycle to update all scope level bindings.

    Here in your case you are updating angular scope variable from custom event, so you need to run digest cycle manually by doing $apply() method on scope

    Code

    elem.bind("keydown keypress", function(event) {
        if (event.which === 16) {
           $('.iconclass').attr("tabIndex", -1).focus();
           scope.focusToSpan = true;
           scope.$apply();
        }
    });