更新md-progress-linear而不触发$ digest

时间:2015-12-01 07:45:07

标签: angularjs angular-material

md-progress-linear的{​​{3}}声明如下:

<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

3 个答案:

答案 0 :(得分:2)

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

,而不是使用$ interval

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

答案 1 :(得分:1)

这不完全正确:

$ interval会触发 $ apply 调用,而非 $ digest 。区别在于(基本上)$ apply调用将导致来自整个范围树的所有手表(来自$ rootScope),其中$ digest仅针对给定范围(以及它的孩子)

如果你知道interval调用的方法只会影响给定的范围树(也就是:范围和它的子树)而不是整个rootScope树,你可以改善性能,而不是:

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

'false'4th param是“invokeApply = false”,要求在方法执行后不要调用$ rootScope.apply。相反,您在方法结束时手动调用范围内的$ digest(您甚至可以在条件为真的情况下触发摘要,避免在处理程序什么都不做的情况下的摘要周期。)

(第三个参数是重复计数,需要添加4rth参数.. 0 - &gt;无限重复,就像只调用2个参数一样)

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

这是你能做的最好的事情,因为在没有$ digest周期的情况下,没有办法让md-process-linear更新。

(使用自定义指令,您可以按照事件而不是监视工作,但是对于这种需求,这似乎过于复杂,调用有针对性的$ digest而不是$ apply,大部分时间,确实足够,性能 - 明智)

答案 2 :(得分:0)

我的解决方案基于Pierre's answer

之前

检查/更新所有PageController $watch

<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

<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(); });
}