我有严重的性能问题。
我想在列表中显示详细信息,但该函数调用次数过多。
这是HTML代码:
<div ng-controller="MyCtrl as ctrl">
<p>Watch your console, then click on a letter. Why "myterious" function is launched so many time ???</p>
<button ng-click="ctrl.setValue('B')">Display B</button>
<button ng-click="ctrl.setValue('C')">Display C</button>
<button ng-click="ctrl.setValue('D')">Display D</button>
<div ng-repeat="item in ctrl.vitals track by $index">
<p ng-click="ctrl.toggleDetail($index)" ng-bind="item.name"></p>
<div ng-show="ctrl.myterious(item.name, ctrl.value)">This should only be display under {{item.name}}</div>
<div ng-show="ctrl.display[$index]">...</div>
<br>
</div>
</div>
还有我的JavaScript代码:
var app = angular.module('myApp',[]);
app.controller('MyCtrl', [function() {
var self = this;
self.vitals = [
{name:'A'},
{name:'B'},
{name:'C'},
{name:'D'},
{name:'E'},
{name:'F'},
{name:'G'},
{name:'H'},
{name:'I'},
{name:'J'},
{name:'K'}
];
self.display = [];
self.toggleDetail = function(id) {
console.log("Toggle launched");
self.display[id] = !self.display[id];
};
self.value = 'B';
self.setValue = function (val) {
self.value = val;
}
self.myterious = function (a, b) {
console.log(a + ' ' + new Date().getTime());
if (a === b) {
return true;
} else {
return false;
}
}
}]);
我想知道哪里是问题以及如何修复,因为它是我原始代码的简化。
答案 0 :(得分:2)
这是因为只要数据(此处为ng-repeat
)或循环内使用的任何标志,变量等可能已更改,AngularJS就会重新执行ctrl.vitals
循环。
此处,您的mysterious
位于ng-if
内,因此需要在每次迭代时执行。
还有更多细微之处,本文将更好地解释:Banging Your Head Against an AngularJS Issue? Try This
答案 1 :(得分:2)
所有函数调用的原因是ng-show绑定。每次更新DOM时,它都会运行神秘的功能来确定是否显示该项目。为了避免所有这些函数调用,你的ng-show绑定应该基于静态的东西。见下面的修改示例:
self.vitals = [
{name:'A', mysterious: false},
{name:'B', mysterious: true},
{name:'C', mysterious: false},
{name:'D', mysterious: false},
{name:'E', mysterious: false},
{name:'F', mysterious: false},
{name:'G', mysterious: false},
{name:'H', mysterious: false},
{name:'I', mysterious: false},
{name:'J', mysterious: false},
{name:'K', mysterious: false}
];
self.setValue = function (val) {
self.vitals.forEach(function(obj) {
obj.mysterious = obj.name == val
})
self.value = val;
}
<div ng-repeat="item in ctrl.vitals track by $index">
<p ng-click="ctrl.toggleDetail($index)" ng-bind="item.name"></p>
<div ng-show="item.mysterious">
This should only be display under {{item.name}}
</div> </div>
在不知道目标细节的情况下,轻量级函数经常执行以确定dom可见性通常没有任何问题。我唯一一次看到这个问题就是失控。如果您有合理的商业原因来动态计算dom的可见性,请尽可能少地使用它。否则,尽量根据静态(非功能)绑定设计可见性逻辑。
答案 2 :(得分:1)
更准确地说,您的功能被称为两次预期的次数。由于ng-repeat是一个指令,指令可以执行两次或更多次,这是完全正常的。
这已经多次回答,请参阅Why is ng-style function applied twice?以获得一个很好的解释。