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

时间:2016-03-22 15:27:03

标签: angularjs angularjs-scope angularjs-http

我试图在不使用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,但在我的应用中,我收到此错误:

  

无法读取未定义的属性“0”

如果我调试它,则在调用函数时未定义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;
      });
    };
  }
]);

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

1 个答案:

答案 0 :(得分:2)

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

我已经制作了一个示例笔,它可以异步传回您上面使用的示例数据。这样可以扼杀您所做的$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