模板内的函数被多次调用(Angular JS)

时间:2016-01-26 20:37:42

标签: javascript angularjs ng-template

今天我必须解决由此代码引起的性能问题:注意在模板内调用的updateStats

<script type="text/ng-template" id="entityGrouper">

<section>

<div>
<ul ng-click="hideEntityBox = !hideEntityBox">
<li>
{{ entityNode.name }}
</li>
<li ng-repeat="breadcrumbItem in entityNode.breadcrumb">
{{ breadcrumbItem }}
</li>
</ul>
{{ updateStats(entityNode) }}
<span ng-include="'/mypath/views/resume.html'"></span>
</div>

<div>

<div ng-repeat="entityNode in entityNode.group" ng-include="'entityGrouper'"></div>
<div ng-repeat="entity in entityNode.group" ng-include="'entityBox'"></div>

</section>

</script>

使用模板:

<div ng-repeat="entityNode in entityNode.group" ng-include="'entityGrouper'"></div>

调试完这段代码后,我发现这个函数被调用的时间比数组大小多很多(我的数组有4个对象,函数调用次数超过100次),甚至鼠标悬停都调用了这个函数。 我通过在模板中放置一个ng-init来修复它,现在它正常工作,但我没有弄清楚为什么这个函数被调用了很多次。是否有关于双向数据绑定的内容?

3 个答案:

答案 0 :(得分:6)

通常建议在此类情况下使用$watch。由于绑定了函数{{updateStats()}},因此它将在每个摘要周期执行。

因此,无论何时调用摘要周期,它都会在您的代码中调用该函数。并且在Angular内部经常调用摘要周期。

答案 1 :(得分:3)

您所看到的是摘要周期的结果。

添加::将调用该函数一次/一次性绑定。

{{ ::updateStats(entityNode) }}

答案 2 :(得分:3)

这不是因为双向数据绑定(它适用于表单输入),而是因为角度变化检测。 Angular会定期检查绑定到模板的任何值是否发生了更改,如果是,则更新其在视图中的值。通常,它由用户生成的事件触发。为了检查updateStats(entityNode)的值是否发生了变化,Angular会对其进行评估,从而导致性能下降。

要解决此问题,您可以使用前面提到的一次性绑定updateStats(entityNode) ,如果结果设置一次并且将来永远不会更改。我想,这是你的情况,你已经将评估转移到ng-init。对于随时间更新的值,最好在entityNode中创建一个单独的属性,例如entityNode.stats,在模板中显示该属性,并仅在必要时在控制器或服务中运行updateStats(entityNode) 。通过这样做,您将阻止在每个摘要周期运行updateStats(entityNode)(您已经看到了这种情况的频率),从而提高了应用程序的性能。