我会说调用$ scope。$ apply或$ scope。$ digest通常(虽然不总是)一个坏主意。
对于你的例子,注册DOM事件可以通过使用ng-click,ng-keydown等角度来完成,这将隐藏调用$ apply或$ digest的需要。
它甚至需要的原因很明显是因为有一些代码在角度外执行“外部”角度,这意味着角度生态系统之外,所以基本上角度不会“知道”事件(或任何其他数据相关事物)发生了。
所以总结一下,应该有一个很好的理由来调用$ apply或$ digest。
还有其他吗?那么,你可以在你自己的指令中封装这些事件捕获(虽然大多数如果不是全部都是角度覆盖的话)。这些角度本身就是这样做的,并且仅在事件本身实际需要时才会导致$ apply或$ digest。
/编辑/
例如,角度的NG-点击的简化版本,可以翻译成你自己的指令:
app.directive('myClick', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var clickHandler = $parse(attr.myClick);
element.on('click', function(event) {
// Do some of your own logic if needed.
scope.$apply(function() {
// Calling the event handler.
clickHandler(scope, {$event: event});
});
});
}
}
}]);
通过封装此事件处理程序,它可以重复使用(在此一个指令形式),并且因为是角度世界的一部分,所以使用此指令的任何其他逻辑都不必担心$ apply或$ digest。这也意味着它现在可以使用声明(而不是操作上),这是什么角度渴望。
有一点需要注意,这个指令没有隔离的作用域,也没有在作用域上引入任何其他的新变量(事件处理函数在链接函数中被解析)。这很重要,因为这意味着对父范围(需要“知道”这个事件的范围 - 基本上是主范围)没有额外的副作用,因为指令的范围是继承的。
P.S您还可以考虑overriding指令或decorating其他服务的角度。
你能否详细说明“封装这些事件”? – 2014-11-05 15:24:33
查看附件。 – Tomer 2014-11-06 06:57:56
所以这是我没有得到 - 如果我点击一个按钮,而我已经在一个摘要循环中会发生什么? – 2014-11-07 07:47:05