如何在没有ngRepeat的情况下获取数组的长度

How to get the length of an array without ngRepeat

我试图在不使用 ng-repeat 的情况下计算数组中的项目(我真的不需要它,我只想打印出总和)。

这是我目前所做的:http://codepen.io/nickimola/pen/zqwOMN?editors=1010

HTML:

<body ng-app="myApp" ng-controller="myCtrl">
    <h1>Test</h1> 
    <div ng-cloak>{{totalErrors()}}</div>
</body>

Javascript:

angular.module('myApp', []).controller('myCtrl', ['$scope', '$timeout', function($scope) {

    $scope.tiles= {
            'data':[
                {'issues':[
                    {'name':'Test','errors':[
                        {'id':1,'level':2},
                        {'id':3,'level':1},
                        {'id':5,'level':1},
                        {'id':5,'level':1}
                    ]},
                    {'name':'Test','errors':[
                        {'id':1,'level':2,'details':{}},
                        {'id':5,'level':1}
                    ]}
                ]}
            ]}
  $scope.totalErrors = function() {
  if ($scope.tiles){
        var topLevel = $scope.tiles.data
        console.log (topLevel);
   return topLevel[0].issues.map(function(o) {
            return o.errors.length
          })
          .reduce(function (prev, curr){
            return prev + curr
          })
    }
    }
}]);

此代码适用于 codepen,但在我的应用程序中出现此错误:

Cannot read property '0' of undefined

如果我调试它,调用函数时 topLevel 是未定义的。

我认为这与数据加载有关,因为在我的应用程序上我有一个如下所示的服务:

angular.module('services', ['ngResource']).factory('tilesData', [
  '$http', '$stateParams', function($http, $stateParams) {
    var tilesData;
    tilesData = function(myData) {
      if (myData) {
        return this.setData(myData);
      }
    };
    tilesData.prototype = {
      setData: function(myData) {
        return angular.extend(this, myData);
      },
      load: function(id) {
        var scope;
        scope = this;
        return $http.get('default-system.json').success(function(myData) {
          return scope.setData(myData.data);
        }).error(function(err) {
          return console.error(err);
        });
      }
    };
    return tilesData;
  }
]);

然后我将这样的数据加载到我的控制器中:

angular.module('myController', ['services', 'ionic']).controller('uiSettings', [
  '$scope', '$ionicPopup', '$ionicModal', 'tilesData', function($scope, $ionicPopup, $ionicModal, tilesData) {
    $scope.tiles = new tilesData();
    $scope.tiles.load();
    $scope.totalErrors = function() {
      debugger;
      var topLevel;
      topLevel = $scope.tiles.data;
      console.log(topLevel);
      return topLevel[0].issues.map(function(o) {
        return o.errors.length;
      }).reduce(function(prev, curr) {
        return prev + curr;
      });
    };
  }
]);

但我不知道如何解决这个问题。任何帮助将不胜感激。非常感谢

$http.get() 方法是 异步的 ,因此您可以在控制器中使用 回调或承诺 来处理此问题。我在这里有一个使用承诺的例子。

我制作了一个示例笔,它传回您在上面使用的示例数据 asynchronously.This 模拟您进行的 $http.get 调用。

我在控制器中处理异步调用的方式与您所做的略有不同,但这种方式与承诺使用的 .then() 模式一起工作。这应该为您提供一个示例,说明如何在控制器中处理异步代码。

另请注意,我的服务与我的控制器位于同一模块中。这应该无关紧要,按照您完成的方式,将工厂模块注入主模块就可以了。

angular.module('myApp', [])

//Define your controller
.controller('myCtrl', ['$scope','myFactory', function($scope,myFactory) {        
    //call async function from service, with .then pattern:
    myFactory.myFunction().then(
    function(data){
        // Call function that does your map reduce
        $scope.totalErrors = setTotalErrors();
    },
    function(error){
        console.log(error);
    });

  function setTotalErrors () {
    if ($scope.tiles){
                var topLevel = $scope.tiles.data
                console.log (topLevel);
     return topLevel[0].issues.map(function(o) {
                        return o.errors.length
                    })
                    .reduce(function (prev, curr){
                        return prev + curr
                    });
        }
 }
}])
.factory('myFactory', ['$timeout','$q',function($timeout,$q){
return {
    myFunction : myFunction
};

function myFunction(){
    //Create deferred object with $q.
    var deferred = $q.defer();
    //mock an async call with a timeout
    $timeout(function(){
        //resolve the promise with the sample data
        deferred.resolve(
            {'data':[
            {'issues':[
                {'name':'Test','errors':[
                    {'id':1,'level':2},
                    {'id':3,'level':1},
                    {'id':5,'level':1},
                    {'id':5,'level':1}
                ]},
                {'name':'Test','errors':[
                    {'id':1,'level':2,'details':{}},
                    {'id':5,'level':1}
                ]}
            ]}
        ]})
    },200);

    //return promise object.
    return deferred.promise;
}
}]);

看看:Link to codepen

此外,请阅读 $q 文档:documentation