【问题标题】:service does not return data to controller in angular服务不会以角度向控制器返回数据
【发布时间】:2016-03-26 13:22:35
【问题描述】:

这是我的服务:

app.service('trackService', ['$http', function($http) {
    var data;
    this.topTracks = function(limit) {
        $http({
            method: 'GET',
            url: 'http://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks',
            params: {api_key: 'e8452c5962aafbb3e87c66e4aaaf5cbf', format: 'json', limit: limit}
        }).success(function(result) {
            this.data = result.tracks; console.log(this.data); return this.data;
        }); 
    }
}]);

和控制器 -

app.controller('artistSongsCtrl', ['$scope', 'trackService', function($scope, trackService) {
    $scope.data = trackService.topTracks(10);
    //console.log($scope.data);
}]);

如何使用自定义服务中的 $http 服务向控制器发送数据?

【问题讨论】:

    标签: javascript angularjs json angular-services


    【解决方案1】:

    有几个问题是$http 是异步的,您的服务方法topTracks() 不返回任何内容。你也不能在success里面返回,没有地方可以返回......改用then()

    您需要从服务返回承诺并在控制器的承诺回调中设置范围

    app.service('trackService', ['$http',
      function($http) {
        var data;
        var self = this;
        this.topTracks = function(limit) {
          return $http({
            method: 'GET',
            url: 'http://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks',
            params: {
              api_key: 'e8452c5962aafbb3e87c66e4aaaf5cbf',
              format: 'json',
              limit: limit
            }
          }).then(function(result) {
            self.data = result.data.tracks;
            console.log(self.data);
            return self.data;
          });
        }
      }
    ]);
    
    app.controller('artistSongsCtrl', ['$scope', 'trackService',
      function($scope, trackService) {
        trackService.topTracks(10).then(function(data) {
          $scope.data = data;
          //console.log($scope.data);
        });
    
      }
    ]);
    

    【讨论】:

    • .log($scope.data) 出错 => angular.min.js:111 TypeError: Cannot read property 'then' of undefined
    • 可能没有按照 asnwer 中显示的代码在服务中执行return $http
    • stackoverflow.com/users/1175966/charlietfl 我明白了,谢谢。告诉我控制器中的一件事,$scope.data 外部服务不可用。如果我愿意,怎么做?
    • function($scope, trackService) { trackService.topTracks(10).then(function(data) { $scope.data = data; //console.log($scope.data); = > 好 }); ////console.log($scope.data); => 未定义
    • Oooooh ... thisthen() 内的服务内有大问题。使用self 查看更新。我以前应该注意到的。在 successthen 等任何回调中,this 都不相同
    【解决方案2】:

    在您的服务中,您正在发出异步 GET 请求。为了让控制器捕获该响应,您需要返回一个承诺。这是一个使用 $q 的示例:

    app.service('trackService', ['$http', '$q', function($http, $q) {
        var data;
        this.topTracks = function(limit) {
            var d = $q.defer();
            $http({
                method: 'GET',
                url: 'http://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks',
                params: {api_key: 'e8452c5962aafbb3e87c66e4aaaf5cbf', format: 'json', limit: limit}
            }).success(function(result) {
                this.data = result.tracks; 
                console.log(this.data); 
                d.resolve(this.data);
            }); 
         return d.promise;
        }
    }]);
    

    【讨论】:

    • 这是一个使用$q的反模式...$http已经返回promise,不需要创建一个新的
    • @charlietfl 感谢您的链接和评论。我确实对此有疑问。如果您需要在解决之前对响应进行一些操作怎么办?就像在这个例子中,他想将响应存储在服务中 + 记录它。
    • 像我一样使用then()。可以在那里进行任何操作。 then() 中的返回值在链中的下一个 then() 中可用。请注意,$http 文档显示 success 出于这个原因已弃用
    • @charlietfl 谢谢!刚刚在我的代码上进行了测试......很好学。我将编辑我的答案并参考您的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2015-09-07
    • 2015-11-15
    • 2019-04-20
    • 2015-12-02
    相关资源
    最近更新 更多