2016-03-22 2 views
0

Я пытаюсь подсчитать элементы в массиве без использования ng-repeat (мне это действительно не нужно, я просто хочу распечатать сумму).Как получить длину массива без ngRepeat

Это то, что я сделал до сих пор: 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, но на моем app Я получаю эту ошибку:

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; 
     }); 
    }; 
    } 
]); 

но я не знаю, что делать, чтобы решить эту проблему. Любая помощь будет действительно оценена. Большое спасибо

+0

В службе, функция загрузки: 'вернуть scope.setData (MyData)'. –

+0

Похоже, вы исправили, он ... собирается на кофейные показы 6 на странице. –

+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

+0

Вы кодируете швы, чтобы работать, но я набрал неправильный файл json, и теперь я немного застрял, можете ли вы проверить этот код? пожалуйста? Мне нужно перебирать список массивов, поэтому topLevel [0] .issues.map не работает: http://codepen.io/nickimola/pen/zqwOMN?editors=1010 – Nick

+0

Вам нужно будет перебирать оба массива и массивы ошибок в массивах, чтобы это работало. Вы могли бы называть что-то похожее на вашу карту и уменьшать количество звонков внутри ваших карт на верхнем уровне – dafyddPrys

+0

. Я сделал это так: http://codepen.io/nickimola/pen/zqwOMN?editors=0010, но я получаю «не могу прочитать свойство» 0 'в нуле, а в консоли - правильное значение. – Nick

Смежные вопросы