Единичное тестирование директивы AngularJS, которая отслеживает атрибут с областью выделения

У меня есть директива, которая использует область изоляции для передачи данных в директиву, которая изменяется со временем. Он следит за изменениями этого значения и делает некоторые вычисления при каждом изменении. Когда я пытаюсь выполнить unit test директиву, я не могу заставить часы запускаться (обрезается для краткости, но базовая концепция показана ниже):

Директива

angular.module('directives.file', [])
.directive('file', function() {
  return {
    restrict: 'E',
    scope: {
      data: '=',
      filename: '@',
    },
    link: function(scope, element, attrs) {
      console.log('in link');
      var convertToCSV = function(newItem) { ... };

      scope.$watch('data', function(newItem) {
        console.log('in watch');
        var csv_obj = convertToCSV(newItem);
        var blob = new Blob([csv_obj], {type:'text/plain'});
        var link = window.webkitURL.createObjectURL(blob);
        element.html('<a href=' + link + ' download=' + attrs.filename +'>Export to CSV</a>');
      }, true);
    }
  };
});

Тест:

describe('Unit: File export', function() {
  var scope;

  beforeEach(module('directives.file'));
  beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();
  };

  it('should create a CSV', function() {
    scope.input = someData;
    var e = $compile('<file data="input" filename="filename.csv"></file>')(scope);
    //I've also tried below but that does not help
    scope.$apply(function() { scope.input = {}; });
  });

Что я могу сделать, чтобы вызвать часы, поэтому я запускаю инструкцию отладки "В часах"? Моя "Входящая ссылка" запускается при компиляции.

Ответ 1

При срабатывании $watch цикл дайджест должен произойти в той области, в которой она определена, или на ее родительском элементе. Поскольку ваша директива создает область изоляции, она не наследуется от родительской области, и поэтому ее наблюдатели не будут обрабатываться до тех пор, пока вы не назовете $apply в правильной области.

Вы можете получить доступ к области директивы, вызвав scope() в элементе, возвращаемом службой $compile:

scope.input = someData;
var e = $compile('<file data="input" filename="filename.csv"></file>')(scope);
e.isolateScope().$apply();

Этот jsFiddler иллюстрирует это.