Angular $watch не работает с переменной контроллера, обновленной директивой

Я пытаюсь поместить часы в переменную контроллера, которая обновляется из директивы с использованием сопоставления функций. переменная обновляется и регистрируется в консоли, но смотреть на нее не работает.

Фрагмент кода:

index.html

<body ng-app="myApp" ng-controller="myCtrl">
<div>
  <test on-click="update()"></test>
</div>

app.js

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

myApp.controller('myCtrl', function($scope){

  $scope.test = {
    value: false
  };

  $scope.update = function() {
    $scope.test.value = !$scope.test.value;
    console.log("Update: " + $scope.test.value);
  };

  $scope.$watch('test', function(newVal){
    console.log("Watch: " + newVal.value);
  }, true);

});

myApp.directive('test', function($compile){
  return {
    restrict: 'E',
    transclude: true,
    replace: true,
    scope: {
      onClick: '&'
    },
        template: '<div ng-transclude=""></div>',
        link: function(scope, element, attrs) {
          var $buttonElem = $('<button>Test</button>').appendTo(element);

          $buttonElem.click(function(){
            scope.onClick();
          });
        }
  }
});

Ссылка на плункер: https://plnkr.co/edit/41WVLTNCE8GdoCdHHuFO?p=preview


comment
Попробуйте вызвать scope.$apply() в функции ссылки.   -  person Kyle    schedule 09.05.2016
comment
Не могу этого сделать. Рассматривайте директиву как стороннюю библиотеку, которую нельзя обновить.   -  person Prateek    schedule 09.05.2016
comment
@Prateek, но вы можете сделать $timeout(function() { $scope.$apply(); }); внутри функции обновления вашего контроллера, которая будет делать то же самое (даже если это уродливо)   -  person Jeff Lambert    schedule 09.05.2016


Ответы (1)


Проблема в том, что директива вызывает событие, используя код, не являющийся частью AngularJS, вместо использования ng-click в своем шаблоне. Если вы не можете изменить директиву, вместо этого оберните обработчик событий в $scope.$apply.

$scope.update = function() {
    $scope.$apply(function(){
        $scope.test.value = !$scope.test.value;
        console.log("Update: " + $scope.test.value);
    });
};
person adam0101    schedule 09.05.2016