在不触发 $digest 的情况下更新 md-progress-linear
Update md-progress-linear without triggering $digest
md-progress-linear
的 demo 声明如下;
<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;
}
md-progress-linear
的 demo 声明如下;
<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 转换
而不是使用 $intervalself.determinateValue = 0
$timeout(function() {
self.determinateValue = 70
}, 100)
md-progress-linear .md-container .md-bar2 {
transition: transform 1.5s linear;
}