我在Angular App中的services.js
中有这段代码:
.factory('Articles', function($http) {
$http.get('https://api.myjson.com/bins/4ici6').then( function(response) {
var articles = response.data.articles;
});
return {
all: function() {
return articles;
},
get: function(articleId) {
for (var i = 0; i < articles.length; i++) {
if (articles[i].id === parseInt(articleId)) {
return articles[i];
}
}
return null;
}
};
})
当我在控制台中收到此错误时,它无法正常工作:
ReferenceError: articles is not defined
at Object.all (http://localhost:8100/js/services.js:31:14)
at new <anonymous> (http://localhost:8100/js/controllers.js:4:30)
at Object.instantiate (http://localhost:8100/lib/ionic/js/ionic.bundle.js:18015:14)
此处还有引用controller.js
的{{1}}代码:
articles
我在这里做错了什么?
答案 0 :(得分:1)
因为$http.get
是异步调用,所以您必须处理它。
只要把它放在工厂的顶部就不会一直工作。
请改为尝试:
.factory('Articles', function($http) {
return {
all: function() {
return $http.get('https://api.myjson.com/bins/4ici6').then(function(response) {
return response.data.articles;
});
},
get: function(articleId) {
//Probably best here to call an API endpoint that will return a single article with the parameter's articleId
//Something along the lines of
//$http.get('https://api.myjson.com/bins/4ic16/' + articleId).then(function(response) { //handle response});
}
};
})
您的控制器也应该更改为处理异步函数调用:
.controller('NewsCtrl', function($scope, Articles) {
Articles.all().then(function(articles) { $scope.articles = articles });
})
答案 1 :(得分:1)
你在http的回调中声明了你的文章变量,所以它不会在它之外可用。将它移到外面:
.factory('Articles', function($http) {
// declaring it here makes it available in the 'all' function
var articles = [];
$http.get('https://api.myjson.com/bins/4ici6').then( function(response) {
articles = response.data.articles;
});
return {
all: function() {
return articles;
},
get: function(articleId) {
for (var i = 0; i < articles.length; i++) {
if (articles[i].id === parseInt(articleId)) {
return articles[i];
}
}
return null;
}
};
})
但是因为您通过http异步获取文章,所以在获取文章之前执行Articles.all()
之前可能会发生这种情况,从而导致数组为空。相反,我会这样做:
.factory('Articles', function($http, $q) {
// declaring it here makes it available in the 'all' function
var articles = [];
var fetched = false;
var getAll = function() {
var deferred = $q.defer();
if (!fetched) {
$http.get('https://api.myjson.com/bins/4ici6').then( function(response) {
articles = response.data.articles;
fetched = true;
deferred.resolve(articles);
});
} else {
deferred.resolve(articles);
}
return deferred.promise;
}
return {
all: getAll,
get: function(articleId) {
var deferred = $q.defer();
getAll().then(function(articles) {
for (var i = 0; i < articles.length; i++) {
if (articles[i].id === parseInt(articleId)) {
deferred.resolve(articles[i]);
break;
}
}
// not found
return deferred.reject();
}
return deferred.promise;
}
};
})
并像这样使用它:
Articles.all().then(function(articles){
// now the articles are available
});
Articles.get(id).then(function(article){
// found
}, function(){
// not found
});