var app = angular.module('app',['ui.bootstrap']);
app.controller("ListCtrl", function ($scope, $http) {
$scope.submit = function () {
$scope.loading = true;
$scope.error = false;
$http.get('http://www.omdbapi.com/?s=' + $scope.search + '&r=json')
.then(function (res) {
var titles = [];
angular.forEach(res.data.Search, function(item){
$http.get('http://www.omdbapi.com/?t=' + item.Title + '&y=&plot=full&r=json').then(function(res){
if (res.data.Poster === "N/A") {
res.data.Poster = "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!";
}
titles.push(res.data);
});
});
$scope.movie = titles;
$scope.results = true;
$scope.error = false;
$scope.loading = false;
if (titles.length==0) { // not working
$scope.results = false;
$scope.error = true;
}
})
我尝试了几件事:
Object.getOwnPropertyNames(titles).length === 0)
obj == null
它们似乎都不起作用......
答案 0 :(得分:2)
由于不正确的范围:
,这种情况正在发生 var titles = [];
在.then
并且您正在检查.then
由于在titles
之外.then
不可用,因此无效。 (undefined.length==0
)
解决方案:
.then(function (res) {
var titles = [];
angular.forEach(res.data.Search, function(item){
$http.get('http://www.omdbapi.com/?t=' + item.Title + '&y=&plot=full&r=json').then(function(res){
if (res.data.Poster === "N/A") {
res.data.Poster = "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!";
}
titles.push(res.data);
});
$scope.movie = titles;
$scope.results = true;
$scope.error = false;
$scope.loading = false;
if (titles.length==0) { // now this will work
$scope.results = false;
$scope.error = true;
}
});//titles will not be available after this.
答案 1 :(得分:0)
$http.get()
是异步的,因此语句if (titles.length==0) {
会立即执行。
有一个计数器来确定所有Promise何时得到解决,然后执行检查。在回调中移动if语句。
var count = res.data.Search.length;
angular.forEach(res.data.Search, function(item){
$http.get('http://www.o....rest of code').then(function(res) {
// rest of code
titles.push(res.data);
if (!count-- && !titles.length) {
$scope.results = false;
$scope.error = true;
}
}
});
});
答案 2 :(得分:0)
在您的情况下,检查
titles.length
将在
之前执行titles.push
因为您使用的是稍后将返回的异步请求。 您需要将语句包装到请求的答案块中。
答案 3 :(得分:0)
除此之外,但对我的实践和未来的帮助有益:
你遇到的部分问题是范围管理(JS范围,而不是Angular $范围),其中一部分是并发管理,其中一部分似乎是简单的旧范围格式化,很难看到所有控制块的开始和结束(当它不仅仅是/ else,而且还有回调/承诺时会变得很糟糕)。
这是一个很小的例子,说明如何通过快速重构问题来解决这些问题:
function pluck (key) {
return function pluckFrom(obj) { return obj[key]; };
}
angular.module("app", ["ui.bootstrap"]);
angular.moule("app").service("omdbService", ["$http", function ($http) {
function getSearch (search) {
var searching = $http.get("http://www.omdbapi.com/?s=" + search + "&r=json")
.then(pluck("data"));
return searching;
}
function getMovie (title) {
var searching = $http.get("http://www.omdbapi.com/?t=" + title + "&y=&plot=full&r=json")
.then(pluck("data"));
return searching;
}
return {
getSearch: getSearch,
getMovie: getMovie,
getPlaceholderPoster: function () { return "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!"; }
};
}]);
angular.moule("app").controller("ListCtrl", ["$scope", "$q", "omdbService", function ($scope, $q, omdb) {
function loadMovie (movie) {
return omdb.getMovie(movie.Title)["catch"](function () { return undefined; });
}
function movieExists (movie) { return !!movie; }
function updatePoster (movie) {
movie.Poster = movie.Poster || omdb.getPlaceholderPoster();
return movie;
}
function setResults (movies) {
$scope.movie = movies; // $scope.movies, instead?
$scope.results = true;
$scope.error = false;
$scope.loading = false;
}
function handleError () {
$scope.results = false;
$scope.error = true;
}
$scope.submit = function () {
$scope.loading = true;
$scope.error = false;
omdb.getSearch($scope.search)
.then(pluck("Search"))
.then(function (movies) { return $q.all(movies.map(loadMovie)); })
.then(function (movies) { return movies.filter(movieExists).map(updatePoster); })
.then(setResults, handleError);
};
}]);

有8000种有效的处理方法,每个人都会看到它有点不同 这也不是我在制作中如何处理它,但也不是太远......
将所有端点调用移出到负责这些操作的服务,这意味着系统中的任何控制器(以该模块作为依赖项)都可以访问它们。
为每个函数做一些小事情并让Array.prototype方法进行迭代(IE8可以在需要时进行填充)意味着每个函数都是超级特定的。
通过将控制器/服务功能包装在数组中并命名它们的依赖关系,它们现在已经缩小了。
submit()
的正文少于10行,并处理各种疯狂的异步内容,但我知道我已经处理了错误,例如其中一部电影返回404(我的代码应该仍然火,剩下的电影,其他人的代码可能没有 - 如果服务器为电影投掷错误,大多数代码将永远不会触发成功或将在程序中一直失败。
现在,我没有检查服务器是否正在为电影"发送正确类型的数据,但情况有所不同。