$ apply vs $digest при тестировании директивы
Если у меня есть директива, которая отвечает на состояние определенного атрибута в области видимости, и я хочу изменить этот атрибут в своем тесте и убедиться, что он отвечает правильно, что является лучшим способом сделать это изменение?
Я видел оба этих шаблона:
scope.$apply(function() {
scope.myAttribute = true;
});
и
scope.myAttribute = true;
scope.$digest();
В чем разница между ними, а что лучше и почему?
Ответы
Ответ 1
scope.$digest()
будет стрелять наблюдателей в текущую область действия и всех его детей. scope.$apply
будет оценивать пройденную функцию и запускать $rootScope.$digest()
.
Первая из них быстрее, так как она должна оценивать наблюдателей для текущей области и ее детей. Второй - медленнее, так как он должен оценивать наблюдателей для $rootScope
и всех его дочерних областей.
Когда в одном из наблюдателей возникает ошибка, и вы используете scope.$digest
, она не обрабатывается через службу $exceptionHandler
, поэтому вам нужно самостоятельно обрабатывать исключение. scope.$apply
использует внутренний блок try-catch
и передает все исключения в $exceptionHandler
.
Ответ 2
Как указывается сама документация, цикл $digest формируется в любое время $scope.$apply
. В соответствии с руководством разработчика на scope
После оценки выражения метод $apply выполняет $digest. В фазе $digest область рассматривает все выражения $watch и сравнивает их с предыдущим значением.
И в соответствии с API-интерфейсом Scope API
Обычно вы не вызываете $digest() непосредственно в контроллерах или в директивы. Вместо этого вызов метода $apply() (обычно изнутри директивы) заставит $digest().
Поэтому вы не должны явно вызывать $digest
, вы вызываете метод $apply
, вызывая цикл дайджеста.