Директива углового тестирования для внешнего API: $ apply и $ digest

0

У меня есть директива Angular, которая подключается к внешнему JavaScript API. Поскольку вызов API не завернут с помощью Angular, мне нужно вызвать $scope.$apply применить обновления из вызова API.

Я делаю это в функции link директивы:

function link(scope, element, attrs) {
  externalService.doSomethingInteresting(
    function(result) {
      scope.$apply(function() {
        scope.applyResult(result);
      });
    }
  );
}

У меня эта служба подделана для моего теста, просто называя обратный вызов с некоторыми законсервированными данными:

function doSomethingInteresting(callback) {
  callback(goodResult);
}

Когда я проверяю эту директиву (Karma + Jasmine), я называю scope.$digest как в Angular test guide.

var rawElement = angular.element("<myDirective></myDirective>");
var element = compile(rawElement)(scope);

scope.$digest();

Однако это приводит к:

Error: [$rootScope:inprog] $digest already in progress

Я понимаю, что это связано с $scope.apply сочетании с scope.$digest() вызова scope.$digest(). Если я не вызываю scope.$digest() то мой element пуст. Поэтому я не знаю, как получить результат вызова API, но также и готов к компиляции.

Спасибо за любые рекомендации.

  • 0
    Я думаю, что вы должны обернуть свой внешний сервис в угловую службу и добавить его в свою директиву. Скрипка
  • 0
    Мне потребовалось некоторое время, чтобы переварить вашу скрипку @ themyth92. Таким образом, вы используете $ timeout, чтобы сделать фальшивый сервис асинхронным. Очень хорошо! Это имеет смысл для меня. Поэтому каждый раз, когда я звоню по поводу фальшивой услуги, я просто сбрасываю время ожидания. Если вы преобразуете это в ответ, я приму это. Спасибо!
Показать ещё 1 комментарий
Теги:

1 ответ

1
Лучший ответ

Вы должны высмеивать свою услугу, используя асинхронный $timeout вместо чисто синхронного кода, чтобы вы не получили уже выполненный Error: $digest already in progress.

module('myApp', function($provide){
  $provide.provider('myService', function() {
    this.$get = function($timeout) {
      return {

        // mock your service
        doSomethingInteresting : function(callback) {
          return $timeout(function() {
            callback(mockData);
          });
        }
      }
    }
  });
});

А затем после вашей scope.$digest() при создании директивы вы можете сбросить $timeout чтобы выполнить обратный вызов.

скрипка

Ещё вопросы

Сообщество Overcoder
Наверх
Меню