【问题标题】:AngularJS: How to get $http result as returned value of a function?AngularJS:如何将 $http 结果作为函数的返回值?
【发布时间】:2015-05-20 04:58:24
【问题描述】:

在我的控制器中,我需要一个函数,它接受一个参数并从服务器返回一个 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 通信永远不会立即返回我需要的数据,因为所有通信都是异步的,所以我需要使用 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 函数的结果返回?
有什么想法吗?

【问题讨论】:

  • 只是return responde.data.Poster
  • 我不明白你的问题;你似乎已经添加了你需要的代码,然后在它周围加上了一条询问如何做的评论,大概没有测试过......

标签: javascript ajax angularjs promise angular-promise


【解决方案1】:

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

【讨论】:

    【解决方案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 就会更改。

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

    使用此示例,您无需返回承诺。

    【讨论】:

    • 谢谢,但它适用于我想为每部电影展示海报的所有结果。
    • @SirwanAfifi 实际上,imgUrl 应该针对每个movie... 我明天会测试它并制作小提琴。
    【解决方案3】:

    这是您的案例的工作jsFiddle。请注意,我已经采取了示例标题。

    您不能在 ng-repeat 中调用该函数。您需要在加载之前获取值,就像使用解析一样。

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

    【讨论】:

      【解决方案4】:

      这是另一种方法,这可能更适合您。

      模板:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-22
        • 2018-11-13
        • 1970-01-01
        • 1970-01-01
        • 2016-12-05
        • 1970-01-01
        • 2022-01-10
        相关资源
        最近更新 更多