AngularJS:如何将$ http结果作为函数的返回值?

时间:2015-03-17 16:31:11

标签: javascript ajax angularjs promise angular-promise

在我的控制器中,我需要一个带参数并从服务器返回URL的函数。像这样:

$scope.getPoster = function(title) {
    return $http.get("http://www.omdbapi.com/?t=" + title + "&y=&plot=short&r=json");
};

在我的视图中,我需要以这种方式传递标题,并为src获取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通信永远不会立即返回我需要的数据,因为所有通信都是异步的所以我需要使用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 ? 
    });
};

所以我的问题是如何将getPoster函数的结果作为结果返回? 有什么想法吗?

4 个答案:

答案 0 :(得分:2)

当您使用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}}'

答案 1 :(得分:2)

如果您将movie传递给getPoster函数,而不是title,它应该有效;并将变量绑定到ng-src而不是返回getPoster函数,它应该可以工作。

此外,您可以在等待响应时显示占位符:

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后,movie.imgUrl会发生变化。

因此,图像将在下一个摘要周期中使用新来源自动更新。

通过此示例,您无需返回承诺。

答案 2 :(得分:1)

以下是您案件的工作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;
                    });


            });
});

答案 3 :(得分:0)

这是另一种方法,这可能对您更有效。

模板:

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