在forEach循环中更新angular $ scope变量

时间:2014-08-18 08:51:28

标签: angularjs performance for-loop angularjs-scope private-members

我有一个非常广泛的过滤器/分面搜索应用程序。 数据通过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;


    }
});

2 个答案:

答案 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;
});