计算 Angular 的$digest周期

Counting Angular's $digest Cycles

本文关键字:digest 周期 Angular 计算      更新时间:2023-09-26

tl;dr:

我想在页面加载时有角度触发 css 动画。有没有办法在控制器或指令中计算角度的摘要周期?


长版本:

我有一些角度动画,我想在页面加载时运行,使用 ng-enter、ng-leave、ng-move 等......带有 ng 重复指令。

从 1.3.6 开始,我知道 angular 会等待应用任何动画,直到发生 2 个摘要周期后,因此这些动画根本不会发生,因为数据(几乎总是(在我的应用程序的第一个摘要周期加载到视图中。(酱料:https://docs.angularjs.org/api/ngAnimate#css-staggering-animations(

我想知道是否有某种方法可以计算摘要周期并触发动画,或者在第二个摘要周期后加载数据?

此外,如果我等到 2 个摘要周期,是否存在在某些情况下第二个周期不会发生的风险,这意味着我的数据不会加载到视图中?如果是这种情况,有没有办法保证每次至少发生 2 个消化周期?

作为临时修复,我使用 $timeout 在 500 毫秒后加载数据,但我知道这是一个非常糟糕的主意。


相关代码:

(由于该项目的保密协议,更改了某些事物的某些名称(

.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);

正如文档中指出的:

如果您希望在调用$digest时收到通知,则可以注册一个没有侦听器的 watchExpression 函数。(由于检测到更改时,watchExpression 可以在每个$digest周期执行多次,因此请准备好对侦听器的多次调用。

因此,您可以使用以下代码计算$digest

var nbDigest = 0;
$rootScope.$watch(function() {
  nbDigest++;
});


更新:说明为什么你不能依赖 HTML,如果你看一下你的开发控制台,你会看到 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>