AngularJS: 如何获取$http结果作为函数的返回值?
AngularJS: How to get $http result as returned value of a function?
在我的控制器中,我需要一个函数,它接受一个参数并从服务器 returned URL。像这样:
$scope.getPoster = function(title) {
return $http.get("http://www.omdbapi.com/?t=" + title + "&y=&plot=short&r=json");
};
在我看来,我需要以这种方式传递标题并获得结果 src
for ng-src
:
<div class="col-sm-6 col-md-3" ng-repeat="movie in movies">
<div class="thumbnail">
<img class="poster" ng-src="{{getPoster(movie.Title)}}" alt="{{movie.Title}}">
<div class="caption">
<h3>{{movie.Title}}</h3>
<p>{{movie.Owner}}</p>
</div>
</div>
</div>
我知道 $http
上的 HTTP 通信永远不会 return 我立即需要的数据,因为所有通信都是异步的所以我需要使用 promise:
$scope.getPoster = function(title) {
$http({ url: "http://www.omdbapi.com/?t=" + title + "&y=&plot=short&r=json" }).
then(function (response) {
// How can I return response.data.Poster ?
});
};
所以我的问题是如何 return 作为 getPoster
函数结果的响应?
有什么想法吗?
因为你正在使用ng-repeat
,你可以传递整个电影对象,然后可以添加一个新的属性给它:
$scope.getPoster = function (movie) {
$http({ url: "http://www.omdbapi.com/?t=" + movie.Title + "&y=&plot=short&r=json" }).
then(function (response) {
// How can I return response.data.Poster ?
movie.imageUrl = response.data.Poster;
});
};
然后绑定ngSrc
:
ng-src='{{movie.imageUrl}}'
如果您将 movie
传递给 getPoster
函数,而不是 title
,它应该可以工作;并将变量绑定到 ng-src
而不是 getPoster
函数的 return,它应该可以工作。
此外,您可以在等待响应时显示一个占位符:
HTML:
<img class="poster"
ng-init="movie.imgUrl = getPoster(movie)"
ng-src="{{movie.imgUrl}}"
alt="{{movie.Title}}">
* 请注意,ng-init
当然可以替换为 控制器内初始化 。
JS:
$scope.getPoster = function(movie) {
$http({ url: "http://www.omdbapi.com/?t=" + movie.Title+ "&y=&plot=short&r=json" })
.then(function (response) {
movie.imgUrl = response.data.Poster;
});
return "/img/poster-placeholder.png";
};
一旦 response
被 returned,movie.imgUrl
就会改变。
因此,图像将在下一个摘要周期中使用新源自动更新。
在这个例子中,您将不需要 return 承诺。
这是您案例的工作 jsFiddle。请注意,我已经采取了样本标题。
您不能调用ng-repeat中的函数。您需要在加载之前获取值,就像使用 resolve 一样。
var app = angular.module('myApp',[]);
app.controller('myCtrl',function($http,$scope){
$scope.movies =[{Title:'gene',Owner:'Alaksandar'},{Title:'alpha',Owner:'Me'}];
angular.forEach($scope.movies,function(movie){
$http.get("http://www.omdbapi.com/?t="+movie.Title+"&y=&plot=short&r=json").
success(function (response) {
movie['poster'] = response.Poster;
});
});
});
这是另一种方法,这可能更适合您。
模板:
<div class="col-sm-6 col-md-3" ng-repeat="movie in getMovies">
<div class="thumbnail">
<img class="poster" ng-src="{{movie.Poster}}" alt="{{movie.Title}}">
<div class="caption">
<h3>{{movie.Title}}</h3>
<p>{{movie.Owner}}</p>
</div>
</div>
服务:
function getMovieData(movies) {
return {
loadDataFromUrls: (function () {
var apiList = movies;
return $q.all(apiList.map(function (item) {
return $http({
method: 'GET',
url: "http://www.omdbapi.com/?t=" + item + "&y=&plot=short&r=json"
});
}))
.then(function (results) {
var resultObj = {};
results.forEach(function (val, i) {
resultObj[i] = val.data;
});
return resultObj;
});
})(movies)
};
};
控制器:
var movies = ["gladiator", "seven"];
$scope.getMovies = getMovieData(movies);
function getMovieData(){
dataService.getMovieData(movies).loadDataFromUrls
.then(getMovieDataSuccess)
.catch(errorCallback);
}
function getMovieDataSuccess(data) {
console.log(data);
$scope.getMovies = data;
return data;
}
在我的控制器中,我需要一个函数,它接受一个参数并从服务器 returned URL。像这样:
$scope.getPoster = function(title) {
return $http.get("http://www.omdbapi.com/?t=" + title + "&y=&plot=short&r=json");
};
在我看来,我需要以这种方式传递标题并获得结果 src
for ng-src
:
<div class="col-sm-6 col-md-3" ng-repeat="movie in movies">
<div class="thumbnail">
<img class="poster" ng-src="{{getPoster(movie.Title)}}" alt="{{movie.Title}}">
<div class="caption">
<h3>{{movie.Title}}</h3>
<p>{{movie.Owner}}</p>
</div>
</div>
</div>
我知道 $http
上的 HTTP 通信永远不会 return 我立即需要的数据,因为所有通信都是异步的所以我需要使用 promise:
$scope.getPoster = function(title) {
$http({ url: "http://www.omdbapi.com/?t=" + title + "&y=&plot=short&r=json" }).
then(function (response) {
// How can I return response.data.Poster ?
});
};
所以我的问题是如何 return 作为 getPoster
函数结果的响应?
有什么想法吗?
因为你正在使用ng-repeat
,你可以传递整个电影对象,然后可以添加一个新的属性给它:
$scope.getPoster = function (movie) {
$http({ url: "http://www.omdbapi.com/?t=" + movie.Title + "&y=&plot=short&r=json" }).
then(function (response) {
// How can I return response.data.Poster ?
movie.imageUrl = response.data.Poster;
});
};
然后绑定ngSrc
:
ng-src='{{movie.imageUrl}}'
如果您将 movie
传递给 getPoster
函数,而不是 title
,它应该可以工作;并将变量绑定到 ng-src
而不是 getPoster
函数的 return,它应该可以工作。
此外,您可以在等待响应时显示一个占位符:
HTML:
<img class="poster"
ng-init="movie.imgUrl = getPoster(movie)"
ng-src="{{movie.imgUrl}}"
alt="{{movie.Title}}">
* 请注意,ng-init
当然可以替换为 控制器内初始化 。
JS:
$scope.getPoster = function(movie) {
$http({ url: "http://www.omdbapi.com/?t=" + movie.Title+ "&y=&plot=short&r=json" })
.then(function (response) {
movie.imgUrl = response.data.Poster;
});
return "/img/poster-placeholder.png";
};
一旦 response
被 returned,movie.imgUrl
就会改变。
因此,图像将在下一个摘要周期中使用新源自动更新。
在这个例子中,您将不需要 return 承诺。
这是您案例的工作 jsFiddle。请注意,我已经采取了样本标题。
您不能调用ng-repeat中的函数。您需要在加载之前获取值,就像使用 resolve 一样。
var app = angular.module('myApp',[]);
app.controller('myCtrl',function($http,$scope){
$scope.movies =[{Title:'gene',Owner:'Alaksandar'},{Title:'alpha',Owner:'Me'}];
angular.forEach($scope.movies,function(movie){
$http.get("http://www.omdbapi.com/?t="+movie.Title+"&y=&plot=short&r=json").
success(function (response) {
movie['poster'] = response.Poster;
});
});
});
这是另一种方法,这可能更适合您。
模板:
<div class="col-sm-6 col-md-3" ng-repeat="movie in getMovies">
<div class="thumbnail">
<img class="poster" ng-src="{{movie.Poster}}" alt="{{movie.Title}}">
<div class="caption">
<h3>{{movie.Title}}</h3>
<p>{{movie.Owner}}</p>
</div>
</div>
服务:
function getMovieData(movies) {
return {
loadDataFromUrls: (function () {
var apiList = movies;
return $q.all(apiList.map(function (item) {
return $http({
method: 'GET',
url: "http://www.omdbapi.com/?t=" + item + "&y=&plot=short&r=json"
});
}))
.then(function (results) {
var resultObj = {};
results.forEach(function (val, i) {
resultObj[i] = val.data;
});
return resultObj;
});
})(movies)
};
};
控制器:
var movies = ["gladiator", "seven"];
$scope.getMovies = getMovieData(movies);
function getMovieData(){
dataService.getMovieData(movies).loadDataFromUrls
.then(getMovieDataSuccess)
.catch(errorCallback);
}
function getMovieDataSuccess(data) {
console.log(data);
$scope.getMovies = data;
return data;
}