我有一个非常广泛的过滤器/分面搜索应用程序。 数据通过API加载,然后使用ng-repeat显示在页面上。还有一个谷歌地图实例,其中包含与每个项目相关联的标记。因此,应用程序在计算方面要求很高。我想我最终可能会使一些客户端的机器超负荷。
这背景足够了。我按照我想要的方式工作。现在,我正在寻找性能提升和更有效的方法来实现我的目标。
现在我试图找出在forEach循环中更新$ scope变量(这是一个数组)是否更好,或更新私有数组然后更新$ scope变量循环?
所以这个
$scope.myArrayWithAllTheItems = [];
$scope.myArrayWithItemKeysToBeDisplayed = [];
$http({method: 'GET', url: '/MYAPIURL'}).success(function(data, status, headers, config) {
if (angular.isArray(data)) {
angular.forEach(data, function (item, key) {
/*
some prework on item object here
*/
//update scope variable with every forEach iteration
$scope.myArrayWithAllTheItems.push({
/*
BIG OBJECT WITH MY DATA
foo : bar,
etc...
*/
});
//I store keys of the items that will be displayed on the page at any one moment
//Changing filter controls will alter this array, not the big one containg all the data
$scope.myArrayWithItemKeysToBeDisplayed.push(key);
});
} else {
//display error...
}
}).error(function(data, status, headers, config) {
//display error...
});
与此相比(我删除了注释和其他分支,但除了2个私有数组之外,其他位相同):
$scope.myArrayWithAllTheItems = [];
$scope.myArrayWithItemKeysToBeDisplayed = [];
$http({method: 'GET', url: '/MYAPIURL'}).success(function(data, status, headers, config) {
if (angular.isArray(data)) {
//private array variables to be update during the loop
var _myArrayWithAllTheItems = [],
_myArrayWithItemKeysToBeDisplayed =[];
angular.forEach(data, function (item, key) {
_myArrayWithAllTheItems.push({
});
_myArrayWithItemKeysToBeDisplayed.push(key);
});
//now update $scope variables only after the loop
$scope.myArrayWithAllTheItems = _myArrayWithAllTheItems;
$scope.myArrayWithItemKeysToBeDisplayed = _myArrayWithItemKeysToBeDisplayed;
}
});
答案 0 :(得分:4)
它完全一样!
更改$ scope变量不会立即强制UI / DOM呈现。实际渲染只会在调用角度$digest()
时发生。
因此,除非你在forEach堆栈的某处强制$digest()
,否则在循环结束之前不会进行渲染,这使得两个选项(基本上)在性能方面都相同。
Check this explanation on how data binding works on AngularJS.
答案 1 :(得分:2)
最好的选择是第三个。理想情况下,您可以将http调用重构为服务,解析数据,然后填充范围项。最佳做法是在控制器中应该具有最小逻辑。要优化代码,您可以在控制器中执行以下操作。
myService.getData().then(function (response) {
$scope.myArrayWithAllTheItems = response.myData;
});