在不触发 $digest 的情况下更新 md-progress-linear

Update md-progress-linear without triggering $digest

md-progress-lineardemo 声明如下;

<md-progress-linear md-mode="determinate" value="{{vm.determinateValue}}">
</md-progress-linear>

然后像这样更新它;

$interval(function() {
      self.determinateValue += 1;    
      if (self.determinateValue > 100) self.determinateValue = 30;
    }, 100);

然而,这将每 100 毫秒触发一次 $digest,导致所有监视和绑定等每 100 毫秒额外更新一次。

有没有一种方法可以显示流畅的动画、确定的 md-progress-linear 而无需在每个刻度上触发 $digest

这不完全正确:

$interval 触发 $apply 调用,而不是 $digest。区别在于(基本上)$apply 调用将导致检查 whole 作用域树中的所有监视(来自 $rootScope),其中 $digest 仅针对 given 范围(及其子级)

如果您知道 interval 调用的方法只会影响给定的作用域树(又名:作用域及其子树)而不是整个 rootScope 树,为了提高性能,您可以改为这样做:

$interval(function() {
      self.determinateValue += 1;    
      if (self.determinateValue > 100) self.determinateValue = 30;
      $scope.$digest();
    }, 100, 0, false);

'false' 第 4 个参数是 "invokeApply=false",要求在方法执行后不要调用 $rootScope.apply。相反,您在方法末尾手动调用范围内的 $digest(您甚至可以仅在条件为真时触发摘要,避免处理程序不执行任何操作时的摘要循环)。

(第三个参数是重复次数,需要添加第4个参数.. 0 -> 无限重复,好像只用2个参数调用)

请注意,如上所述,假设 md-progress-linear 指令的范围是 $scope 或其子项之一,代码示例将起作用。

这是您所能做的最好的事情,因为没有 $digest 循环就无法要求 md-process-linear 进行更新。

(使用自定义指令,您可以按照自己的方式处理事件而不是 watch,但对于这种需要,这似乎过于复杂,在大多数情况下,调用目标 $digest 而不是 $apply 就足够了,性能方面)

我的解决方案基于

之前

所有 PageController $watch 都是 examined/updated.

<div ng-controller="PageController as vm">
    ...
    <md-progress-linear 
        md-mode="determinate" value="{{vm.determinateValue}}">
    </md-progress-linear>
    ...
</div>
function PageController($interval) {
    ...
    $interval(function() {
          self.determinateValue += 1;    
          if (self.determinateValue > 100) self.determinateValue = 30;
    }, 100);
    ...
}

之后

只有 ProgressController $watch 是 examined/updated。

<div ng-controller="PageController as vm">
    ...
    <md-progress-linear 
        ng-controller="ProgressController as vm" 
        md-mode="determinate" value="{{vm.determinateValue}}">
    </md-progress-linear>
    ...
</div>
function PageController($interval, $scope) {
    ...
    $interval(function() {
          self.determinateValue += 1;    
          if (self.determinateValue > 100) self.determinateValue = 30;
          $scope.$broadcast("progress-update");
    }, 100, 0, false);
    ...
}

function ProgressController($scope) {
    $scope.$on("progress-update", function () { $scope.$digest(); });
}

您可以使用 $timeout 并更改 CSS 转换

而不是使用 $interval

self.determinateValue = 0
$timeout(function() {
  self.determinateValue = 70        
}, 100)
md-progress-linear .md-container .md-bar2 {
    transition: transform 1.5s linear;
}