Подсчет Angular $digest Cycles
ТЛ; др:
Я хочу, чтобы анимация css css angular запускалась при загрузке страницы. Есть ли способ подсчета циклов дайджест angular в пределах, скажем, контроллера или директивы?
длинная версия:
У меня есть анимация angular, которую я хочу запустить при загрузке страницы, используя ng-enter, ng-leave, ng-move и т.д. с помощью директивы ng-repeat.
Начиная с версии 1.3.6, я знаю, что angular ждет применения любых анимаций до тех пор, пока не произойдут два цикла дайджеста, поэтому эти анимации вообще не происходят, потому что данные (почти всегда) загружаются в представление на первый цикл дайджеста моего приложения.
(соус: https://docs.angularjs.org/api/ngAnimate#css-staggering-animations)
Мне интересно, есть ли способ подсчета циклов дайджеста и запускать анимацию или загружать данные после 2-го цикла дайджеста?
Кроме того, если я жду до двух циклов дайджестов, существует ли риск того, что второй цикл не произойдет в некоторых случаях, что означает, что мои данные не будут загружаться в представление? Если это так, есть ли способ, которым я могу гарантировать, что каждый раз будет выполняться не менее двух циклов дайджест?
Как временное исправление, я использую $timeout для загрузки моих данных через 500 мс, но я знаю, что это действительно плохая идея.
соответствующий код:
(изменил некоторые имена некоторых вещей из-за NDA в этом проекте)
HTML:
<div ng-repeat="pizza in pizzas" class="za" ng-click="bake(pizza)"></div>
css/sass (префиксы браузера удалены для краткости):
.za {
//other styles
&.ng-enter,
&.ng-leave,
&.ng-move {
transition: all 1s $slowOut;
transform: translate(1000px, 0px) rotateZ(90deg);
}
&.ng-enter,
&.ng-leave.ng-leave-active
&.ng-move, {
transform: translate(1000px, 0px) rotateZ(90deg);
}
&.ng-enter.ng-enter-active,
&.ng-leave,
&.ng-move.ng-move-active {
transform: translate(0, 0) rotateZ(0deg);
}
&.ng-enter-stagger,
&.ng-leave-stagger,
&.ng-move-stagger {
transition-delay: 2s;
transition-duration: 0s;
}
}
JS:
// inside a controller
timeout(function() {
scope.pizza = [ // actually injecting 'myData' and using `myData.get()` which returns an array of objects
{toppings: ['cheese', 'formaldehyde']},
{toppings: ['mayo', 'mustard', 'garlic']},
{toppings: ['red sauce', 'blue sauce']}
];
}, 500);
Ответы
Ответ 1
Как указано в документации:
Если вы хотите получать уведомления при вызове $digest, вы можете зарегистрировать функцию watchExpression без прослушивателя. (Так как watchExpression может выполнять несколько раз за цикл $digest при обнаружении изменения, будьте готовы к нескольким вызовам вашего слушателя.)
Итак, вы можете считать $digest
следующим кодом:
var nbDigest = 0;
$rootScope.$watch(function() {
nbDigest++;
});
Обновление: иллюстрация о том, почему вы не можете полагаться на HTML, если вы посмотрите на свою консоль dev, вы увидите, что Angular жалуется на то, что не сможет завершить цикл digect (аборт после 10 циклов)
angular.module("test", []).controller("test", function($scope) {
$scope.digestCount = 0;
$scope.incrementDigestCount = function() {
return ++$scope.digestCount;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="test" ng-controller="test">
<div>{{incrementDigestCount()}}</div>
</body>