2015-10-14 85 views
0

如何在手动选择的手表上运行摘要循环?例如,我想要一个显示当前时间(秒)的指令,但我不想每秒都触发摘要循环。一种解决方案是更新angular's digest循环外部的值(使用jQuery)。其他方案?AngularJS观察列表排除

谢谢。

+1

您可以通过调用'$ scope。$ digest'而不是'$ scope。$ apply'来限制(有点)摘要的范围。前者只会在$ scope的子树上触发一个摘要,而后者会触发根范围的摘要。 –

+0

喜欢它。你应该发布这个答案。 – user3043893

回答

1

一种方法来“限制”的消化作用是只在当前范围及其子女运行摘要。这是通过$scope.$digest()完成的。

相比之下,$scope.$apply()从根范围调用摘要,因此在这个意义上它与做$rootScope.$digest()相同。

编辑:

如果您正在使用$timeout/$interval,然后确保到invokeApply参数设置为false,否则会从根触发摘要。

0

使用angulars $interval()替代javascripts setInterval为您的时钟。 $interval会照顾摘要。

https://docs.angularjs.org/api/ng/service/ $间隔

更新:

其实,我在项目中的时钟指示我目前工作:

指令:

app.directive('clock', ['$interval', 'dateFilter',function($interval, dateFilter) { 

return { 
    restrict: 'E', 
    scope:  { 
    format: '=', 
    }, 
    link: function (scope, element, attrs) { 
    var format; 
    var stopTime; 

    // set the time in the directive 
    function setTime() { 
     element.text(dateFilter(new Date(), format)); 
    } 

    // update the UI on change. 
    scope.$watch(attrs.format, function(value) { 
     format = value; 
     setTime(); 
    }); 

    format = attrs.format; 
    updateTime(); 
    stopTime = $interval(setTime, 1000); 

    element.on('$destroy', function() { 
     $interval.cancel(stopTime); 
    }); 
    } 
}; 

}]); 

用法:

<clock format="'H:mm'"></clock> 
+0

这不是解决方案。使用$ interval会触发另一个带脏检查的摘要循环。我正在寻找一种方法来避免这种情况,同时仍然使用angular的标准API并只更新DOM的一小部分。 – user3043893

1

你的时钟指令可能会使用$timeout$interval,它具有以下特征:

$timeout([fn], [delay], [invokeApply], [Pass]); 
$interval(fn, delay, [count], [invokeApply], [Pass]); 

通知的invokeApply参数。如果将其设置为false,则角度将为跳过脏检查。

+0

不调用应用意味着DOM对象不会被更新? – user3043893

+0

模型上的更改不会反映在视图中。你必须自己更新DOM,是的。 –

+1

如果你想避免触发摘要,我实际上认为没有什么魔法:你必须在角度范围之外完成这项工作。使用带有* invokeApply *到'false'的'$ interval'只是为了* consistency *,以避免你在'setInterval'和'$ interval'之间混合。 –

0

我会建议使用debounce实用程序函数包装您的观​​察器。 大卫沃尔什提供了一个相当可爱的solution。 下面是一个简单demo

angular.module('watchApp', []).controller('watchCtrl', function ($scope) { 
    $scope.count = 0; 
    $scope.b = Date.now(); 


    $scope.$watch("b", _debounce(function (b) { 

     $scope.$apply(function() { 
      $scope.b = Date.now(); 
      $scope.count += 1; 
     }) 
    }, 1000)); 
}); 
+0

这确实每秒调用'$ apply'。我认为D.沃尔什想在这里避免在一秒钟内触发多个'$ apply'。 –

+0

我真的不明白你的观点。仅仅因为控制器的隔离范围不能“意识到”超时已结束且模型未更新,所以使用“$ apply”。这只是我对解决问题的尝试,因为我讨厌使用JS功能构建的注入,像'$ timeout'或'$ interval'这样的变异的Angular包装。 – Theodore