【问题标题】:Best way to set $scope value from $http service in AngularJS在 AngularJS 中从 $http 服务设置 $scope 值的最佳方法
【发布时间】:2015-12-29 16:08:10
【问题描述】:

我愿意从 AngularJS 中的 $http 服务中获取一个值,并将其设置在 $scope.listing 中。因为这是异步操作 $scope.listing 在页面加载时为空。我看到了一些使用 promise 和 factory 来解决它的实现,但这对我来说感觉有点矫枉过正。有什么优雅的方法吗?

看起来是这样的:

$http.get('/getlisting/')
.success(function(response) {
            $scope.listing = response;
    })
console.log ($scope.listing) // is empty

【问题讨论】:

  • 将 console.log 语句移动到成功处理程序中。当 promise 被解决时,它实际上会被调用。这不是矫枉过正,这是异步“东西”的工作原理
  • 无法绕过承诺,因为 $http API 基于 $q 服务公开的延迟/承诺 API。至于在哪里进行调用,在服务中进行调用,尤其是在多个控制器中使用数据时,是普遍接受的方法。此外,.success 已被弃用,取而代之的是 .then
  • 请缩小您的问题范围。顺便说一句,视图是在控制器运行之前编译的,因此,除非您深入了解 Angular,否则您将无法在数据初始化的情况下显示您的视图。

标签: javascript angularjs http asynchronous


【解决方案1】:

如下修改代码

$http.get('/getlisting/')
.success(function(response) {
        $scope.listing = response;
        console.log ($scope.listing) // is empty
})

您当前的 console.log 甚至在响应来自服务器之前就已被执行,因此它没有打印任何内容... 如果你把它移到.success 里面,你会看到这个值被打印到控制台

【讨论】:

  • 是的。代码已经尽可能简单、清晰和“优雅”了。它已经在 .success 处理程序中使用了一个 Promise,因此无需添加另一个 Promise。真的没有什么能让它更优雅的了。
  • 当然,将 console.log 移到 .success 会解决问题,但我需要在 .success 之外使用它。我只是把它写在那里以可视化问题。
【解决方案2】:

如果您希望在用户到达特定页面时填充 $scope.listing,您可以利用 ui-router 的解析。您基本上是在告诉路由器在您的 $http 调用返回所请求的数据(列表)之前不允许用户访问该页面。

见: http://www.jvandemo.com/how-to-resolve-angularjs-resources-with-ui-router/

【讨论】:

    【解决方案3】:

    始终使用服务和 primise 来处理 http 调用。

    angular.module('App').factory('Request',['$q','$http',function($q,$http){
      return {
        send : function(conf){
          var defer = $q.defer();  
          $http(conf).success(function(response) {
              defer.resolve(response);
          }).error(function(err){
              defer.reject(err);
          });
          return defer.promise;
        }
      };
    }])
    

    在你的控制器中

    angular.module('App').controller('MainCtrl',['$scope','Request',function($scope,Request){
     var conf = {
       url : 'some url',
       method : 'GET/POST/PUT/DELETE etc...',
       data : {some : 'data'}
     }; 
    
     Request.send(conf).then(function(response){
        // todo handle success response here 
     }).catch(function(err){
        // todo handle http error here
     });
    }]);
    

    【讨论】:

    • @georgeawg 反模式?能否请您指出上面代码中的错误之处?
    • 当然,但是这样做我们只编写一次http构造。它只是http服务的包装器。怎么了 ?编写包装器?
    • 此外,.success.error 方法已被弃用。见弃用通知——docs.angularjs.org/api/ng/service/$http#deprecation-notice
    猜你喜欢
    • 1970-01-01
    • 2017-06-28
    • 2014-09-05
    • 2013-07-26
    • 2018-05-21
    • 1970-01-01
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多