$animate.removeClass 在没有 $evalAsync inside 指令的情况下不起作用

$animate.removeClass not working without $evalAsync inside directive?

本文关键字:指令 情况下 不起作用 inside animate removeClass evalAsync      更新时间:2023-09-26

我创建了一个指令,该指令在模型更改时淡出和淡入视图。

app.controller('myCtrl', function($scope, $interval) {
  $scope.number = 0;
  $interval(function() {
    $scope.number++;
  }, 1000);
});
app.directive('fadeOnChange', function($timeout, $animate) {
  return {
    restrict: 'E',
    //We output the value which will be set between fades
    template: '{{theFadedValue.nv}}',
    link: function(scope, elem, attr) {
      //The scope variable we will watch
      var vtw = attr.valueToWatch;
      //We add the anim class to set transitions
      $animate.addClass(elem, 'anim');
      //We watch the value 
      scope.$watch(vtw, function(nv) {
        //we fade out
        var promise = $animate.addClass(elem, 'fade-it-out');
        //when fade out is done, we set the new value
        promise.then(function() {
          scope.$evalAsync(function() {
             scope.theFadedValue = {"nv": nv};
            //we fade it back in
            $animate.removeClass(elem, 'fade-it-out');
          });
        });
      })
    }
  };
});

这是视图

<div ng-controller="myCtrl">
  <h1><fade-on-change value-to-watch="number"></fade-on-change></h1>
</div>

它运行良好,但我想了解为什么我需要使用 $apply、$digest、$timeout 或 $evalAsync 来包装我对 $animate.removeClass 的调用才能使其工作?如果我不这样做,这门课就不会被删除(这让我今天下午很头疼)。

我对这四种方法很感兴趣,并了解它们的不同之处,但在这种情况下需要使用其中一种方法让我感到困惑。

普伦克

基本上异步方法不会直接运行$digest循环。$http的特殊情况,因为它内部包裹在$scope.$apply()

在您的情况下,您正在等待异步的完整承诺。这就是为什么你可以使用$timeout(function(){ })$evalAsync,这个角度服务包装在$scope.$apply()&$scope.$apply()内部运行摘要循环,所有作用域变量都会更新。

$evalAsync在 DOM 被 Angular 操纵后运行,但是 在浏览器呈现之前

此处链接以获取有关何时使用$scope.$apply()的更多信息

希望这能消除您的疑虑。谢谢。