Search code examples
javascriptangularjsangular-directivetwo-way

Two-way binding inside AngularJS directive work with ng-click, but not work with window.onclick


Can anybody explain, why when I click on my element vm.random updated inside element, but when I click just on window vm.random not updates on view layer (but console.log print new value), although both events fire same function vm.update()

<!DOCTYPE html>
<html>

<head>
  <script data-require="[email protected]" data-semver="1.5.9" src="https://code.angularjs.org/1.5.8/angular.js"></script>
  <script>
    var app = angular.module('test', [])
      .directive('testDir', function() {
        return {
          controllerAs: 'vm',
          bindToController: true,
          controller: function() {
            var vm = this;
            vm.random = Math.random();

            window.onclick = function() {
              vm.update();
            };

            vm.update = function() {
              vm.random = Math.random();
              console.log(vm.random);
            };
          },
          template: '<div ng-click="vm.update()">Random number after click {{vm.random}}<input ng-model="vm.random"/></div>'
        }
      });
  </script>
</head>

<body ng-app="test">
  <h1>My directive</h1>
  <test-dir></test-dir>
</body>

</html>

What should I change in this snippet for able to update vm.random after window.onlick change vm.random ?


Solution

  • Try this:

    window.onclick = funciton(){
        $scope.$apply(function(){
            vm.update();
        });
    }
    

    Remember to inject $scope into your controller

    Even though vm.random is not directly on your $scope, angular still needs to know, that it has changed. calling $scope.$apply manually takes care of that.

    The reason it works with ng-click is, that angular directives automatically takes care of $scope.$applying