ng-mousemove触发无关函数求助:如何阻止test1()随鼠标移动重复执行?
解决AngularJS ng-mousemove触发无关函数重复调用的问题
问题原因
你遇到的问题本质是AngularJS的脏检查机制导致的:当ng-mousemove触发test()函数时,Angular会启动$digest循环,检查所有绑定的表达式是否有变化。模板里的{{test1(n)}}属于绑定表达式,每次$digest循环都会重新执行这个函数来对比值是否变化,所以鼠标移动时的每一次事件都会触发test1()反复执行。
解决方案
方案1:预计算结果(推荐)
提前在控制器里计算好test1()的结果,把结果存在数组中,模板直接渲染预计算好的值,避免在模板里调用函数。
修改后的代码:
<!DOCTYPE html> <html> <head> <title>ng-mousemove Directive</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script> </head> <body ng-app="app" style="padding-left:30px;"> <div ng-controller="test"> <div style="height:200px;width:200px;background-color:red" ng-mousemove="test($event)"> <span ng-repeat="item in processedData"> {{item}} </span> </div> </div> <script> var app = angular.module("app", []); app.controller('test', ['$scope', function($scope) { $scope.data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; // 预计算test1的结果 $scope.processedData = $scope.data.map(n => n + 1); $scope.test = function(event) { console.log(event.clientX, event.clientY); return false; }; }]); </script> </body> </html>
方案2:使用一次性绑定(适用于数据不会更新的场景)
如果data数组不会发生变化,AngularJS 1.3及以上版本支持一次性绑定语法{{::test1(n)}},表达式只会在第一次渲染时执行,后续的$digest循环不会再重新计算。
修改模板部分:
<span ng-repeat="n in data"> {{::test1(n)}} </span>
注意:如果后续data数组有更新,一次性绑定的内容不会同步更新,所以只适合静态数据场景。
关键说明
- 永远避免在AngularJS模板表达式里调用耗时函数,因为脏检查会频繁触发这些函数,导致性能问题。
- 预计算是最稳妥的方案,既保证性能,又能兼容数据更新的场景(如果后续需要更新data,只需要重新计算processedData即可)。
内容的提问来源于stack exchange,提问作者Sina Nouri
相关产品推荐
相关产品推荐

