【问题标题】:Undefined $http data when resolved with `.then` method使用 .then 方法解析时未定义的 $http 数据
【发布时间】:2017-08-18 23:50:47
【问题描述】:

我使用了控制台日志,它返回了从服务器获取的数据数组,但是当我在 html 上调用范围时,我在控制台上得到了一个未定义的错误。

app.service('blogpostservice', ['$http', function ($http) {
    this.getMoreData = function (pagecount) {
        return $http.get('/api/posts/' + pagecount);
    }
}]);
app.controller('MainController', ['$scope', 'blogpostservice',
    function ($scope, blogpostservice) {
        $scope.pagec = 1;
        this.getMoreData = function () {
            blogpostservice.getMoreData($scope.pagec).then(function (data) {
                $scope.posts = data;
                console.log($scope.posts);

            })
        }

        this.getMoreData();

    }]);

HTML

 <h1>{{pagec}}</h1>
    <h1>{{posts[1].Title}}</h1>
    <div id="posts" class="grid" ng-repeat="post in posts">
         <div class=" grid-item">
              <div class="blog-post">
                  <img src="https://placeimg.com/400/400/bbc" alt="">
                  <h3>{{post.Title}}</h3>
                  <img ng-src="{{post.Image}}" alt="">         
               </div>
          </div>
    </div>

【问题讨论】:

  • 你是否从这一行得到未定义的错误 console.log($scope.posts); ?
  • 是的,来自帖子[1]。与帖子或帖子相关的所有内容都未定义
  • 您的 html 中是否包含 ng-controller="MainController"?
  • 是的,当然当我使用 {{pagec}} 它显示 1;

标签: angularjs angularjs-scope angularjs-ng-repeat angularjs-http


【解决方案1】:

$http 承诺的.then 方法返回一个response 对象,其中data 是几个属性之一:

app.service('blogpostservice', ['$http', function ($http) {
    this.getMoreData = function (pagecount) {
        return $http.get('/api/posts/' + pagecount);
    }
}]);

app.controller('MainController', ['$scope', 'blogpostservice',
    function ($scope, blogpostservice) {
        $scope.pagec = 1;
        this.getMoreData = function () {
            blogpostservice.getMoreData($scope.pagec)
              ̶.̶t̶h̶e̶n̶(̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶(̶d̶a̶t̶a̶)̶ ̶{̶
              .then(function (response) { 
                ͟v͟a͟r͟ ͟d͟a͟t͟a͟ ͟=͟ ͟r͟e͟s͟p͟o͟n͟s͟e͟.͟d͟a͟t͟a͟;͟
                $scope.posts = data;
                console.log($scope.posts);    
            })
              .catch(function(response) {
                console.log("Error: ", response.status);
                throw response;
            });
        };    
        this.getMoreData();    
    }      
]);

还要确保添加一个.catch 处理程序来记录被拒绝的http 请求。

有关详细信息,请参阅AngularJS $http Service API Reference


更新

我阅读了文档,但连接到主题我遇到的主要问题是将其称为数据而不是函数的响应,对吗?

主要问题是 http 承诺无法解析 data。它解析 response 对象Data 只是response 对象的属性之一:

$http(...)
  .then(function onSuccess(response) {
    // Handle success
    var data = response.data;
    var status = response.status;
    var statusText = response.statusText;
    var headers = response.headers;
    var config = response.config;
    ...
  })
  .catch(function onError(response) {
    // Handle error
    var data = response.data;
    var status = response.status;
    var statusText = response.statusText;
    var headers = response.headers;
    var config = response.config;
    ...
  });

来自文档:

响应对象具有以下属性:

  • data – {string|Object} – 使用转换函数转换的响应正文。
  • status – {number} – 响应的 HTTP 状态代码。
  • headers – {function([headerName])} – Header getter 函数。
  • config – {Object} – 用于生成请求的配置对象。
  • statusText – {string} – 响应的 HTTP 状态文本。
  • xhrStatus – {string} – XMLHttpRequest 的状态(completeerrortimeoutabort)。

200 到 299 之间的响应状态代码被视为成功状态,将导致调用成功回调。超出该范围的任何响应状态代码都被视为错误状态,并将导致调用错误回调。此外,小于 -1 的状态代码被归一化为零。 -1 通常意味着请求被中止,例如使用config.timeout。请注意,如果响应是重定向,XMLHttpRequest 将透明地跟随它,这意味着结果(成功或错误)将由最终响应状态码决定。

— AngularJS $http Service API Reference.

另请注意,-1 状态通常是CORS problem 的症状。由于违反Same Origin Policy,请求被阻止。

【讨论】:

  • 工作,你能解释一下吗?我阅读了文档,但连接到主题我提出的主要问题是将其称为数据而不是函数的响应,对吗?
  • 主要问题是不能解决data。它解析 response 对象Data 只是 response 对象的属性之一。查看更新以回答。
  • 总是使用响应是否明智?
【解决方案2】:

使用回调重写 getMoreData 函数。 请参阅下面的代码示例

app.service('blogpostservice', ['$http', function ($http) {
    this.getMoreData = function (pagecount,callback) {
        var result = $http.get('/api/posts/' + pagecount);
        if(callback){
                    callback(result);
        }
    }
}]);

本质上,由于您不知道 getMoreData 函数何时会从 http get 方法返回值,因此您将 http get 的返回数据传递给回调函数。然后,您可以通过在主控制器中实现回调方法来利用来自 http get 的数据,如下所示:

app.controller('MainController', ['$scope', 'blogpostservice',
    function ($scope, blogpostservice) {
        $scope.pagec = 1;
        this.getMoreData = function () {
            blogpostservice.getMoreData($scope.pagec,function(data){ $scope.posts = data; console.log($scope.posts); })
        }

        this.getMoreData();

    }]);

您还需要确保从 $scope.posts 返回一个数组。

请注意,在您的 html 中,您插入的是 {{post}} 而不是 {{posts}}

【讨论】:

  • 我知道我们不确定返回的结果,所以我们使用回调。现在在控制台中我没有收到任何错误,但我得到了一个包含先前返回的数组的承诺,但 html 仍然不包含任何内容,我无法访问其上的数据
  • 您是否注意到 OP 正在使用ng-repeat="post in posts"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
  • 2014-02-09
  • 2016-06-14
  • 1970-01-01
相关资源
最近更新 更多