模板中的函数被多次调用(Angular JS)
Function inside a template is called many times (Angular JS)
今天我不得不修复由这段代码引起的性能问题:注意模板内部调用的 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 来解决这个问题,现在它可以正常工作了,但我不明白为什么这个函数被调用了这么多次。有关于双向数据绑定的东西吗?
通常建议在这种情况下使用 $watch
。由于您正在绑定一个函数 {{updateStats()}}
,它将在每个摘要周期执行。
因此在您的代码中,每当调用摘要循环时,它也会调用该函数。 Angular 内部经常调用摘要循环。
您看到的是摘要循环的结果。
添加一个::
将调用函数一次/一次性绑定。
{{ ::updateStats(entityNode) }}
发生这种情况不是因为双向数据绑定(它适用于表单输入),而是因为 angular 变化检测。 Angular 定期检查绑定到模板的任何值是否已更改,如果是,则更新其在视图中的值。通常,它由用户生成的事件触发。为了检查 updateStats(entityNode)
的值是否更改,Angular 对其进行评估,这会导致性能下降。
要解决此问题,您可以使用前面提到的一次性绑定updateStats(entityNode)
如果结果设置一次并且将来永远不会更改。我猜,这就是你的情况,你已经将评估移至 ng-init
。对于随时间更新的值,最好在 entityNode
中创建一个单独的 属性,如 entityNode.stats
,将其显示在模板中并 运行 updateStats(entityNode)
仅在必要时在您的控制器或服务中。通过这样做,您将防止 运行ning updateStats(entityNode)
在每个摘要周期(您已经看到它的频率),从而提高您的应用程序的性能。
今天我不得不修复由这段代码引起的性能问题:注意模板内部调用的 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 来解决这个问题,现在它可以正常工作了,但我不明白为什么这个函数被调用了这么多次。有关于双向数据绑定的东西吗?
通常建议在这种情况下使用 $watch
。由于您正在绑定一个函数 {{updateStats()}}
,它将在每个摘要周期执行。
因此在您的代码中,每当调用摘要循环时,它也会调用该函数。 Angular 内部经常调用摘要循环。
您看到的是摘要循环的结果。
添加一个::
将调用函数一次/一次性绑定。
{{ ::updateStats(entityNode) }}
发生这种情况不是因为双向数据绑定(它适用于表单输入),而是因为 angular 变化检测。 Angular 定期检查绑定到模板的任何值是否已更改,如果是,则更新其在视图中的值。通常,它由用户生成的事件触发。为了检查 updateStats(entityNode)
的值是否更改,Angular 对其进行评估,这会导致性能下降。
要解决此问题,您可以使用前面提到的一次性绑定updateStats(entityNode)
如果结果设置一次并且将来永远不会更改。我猜,这就是你的情况,你已经将评估移至 ng-init
。对于随时间更新的值,最好在 entityNode
中创建一个单独的 属性,如 entityNode.stats
,将其显示在模板中并 运行 updateStats(entityNode)
仅在必要时在您的控制器或服务中。通过这样做,您将防止 运行ning updateStats(entityNode)
在每个摘要周期(您已经看到它的频率),从而提高您的应用程序的性能。