Я пытаюсь подсчитать элементы в массиве без использования 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;
});
};
}
]);
но я не знаю, что делать, чтобы решить эту проблему. Любая помощь будет действительно оценена. большое спасибо
Метод $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;
}
}]);
Посмотрите: Ссылка на codepen
Кроме того, прочитайте документацию по $ q: документация
return scope.setData(myData);
,